No.5 表达式中的陷阱
1. 关于字符串的陷阱
- JVM对字符串的处理
- String java = new String("Java"); 创建了几个对象?
- 2个。“Java”直接量对应的字符串对象;new String()构造器返回的字符串对象
- java.intern() 可以字符串池中的直接量对象。
- 字符串及基本类型的包装类,Java允许通过直接量的方式来创建对应的Java对象;除此之外,简单的算术表达式、连接计算(编译时可以确定具体值)也可以直接创建对应的Java对象
- 字符串直接量,JVM会使用一个字符串池保存,第一次使用该直接量时,会将其放在字符串池进行缓存(缓存的意思就是以后再用的话,就直接从池中取,而不会新建啦),一般情况下不会对缓存池中的字符串进行垃圾回收
- 只要是编译时就可以确定其具体值的字符串直接量,JVM会在编译时确定其具体值,并让它指向字符串池中对应的字符串,否则,就不能利用JVM的字符串池了
- 何为编译时确定具体值?
- 没有方法调用;没有变量引用
- 当然,“宏替换”的变量除外
- 何为编译时确定具体值?
- String str = "hello" + “world”; 创建了几个字符串对象
- 1个。因为在编译时就可以确定其计算后的值,因此就直接把计算后的值放到池中就好了,其它的也没有必要啊
- 在使用字符串、基本类型包装类的对象实例时,尽量通过 直接量 来创建实例。可以少创建一个对象,提升性能。
- String java = new String("Java"); 创建了几个对象?
- String是典型的不可变类。可变字符串推荐使用StringBuilder
- 字符串比较
- 底层是字符串数组
- 两个字符串左对齐,依次比较二者的每个字符
2. 表达式类型的陷阱
表达式也是具有制定的数据类型的
- 表达式类型的自动提升
- 当算事表达式中含有多个基本数据类型时,整个表达式的数据类型会自动提升,提升到与表达式中最高等级操作数同样的类型。
- 操作数的等级排列如图示

- 复合赋值运算符的陷阱(+=、-=、/=、...)
- E1 op= E2 等价于 E1 = (E1的类型)(E1 op E2)
- eg:a += 5 等价于 a = (a的类型)(a + 5)
- 陷阱:它潜在的隐式转换 可能 导致计算结果的 高位“截断”(结果强制转换发生溢出时)
3. 输入法导致的陷阱
- 代码中 含有 全角空格。。。提示:“非法字符:\12288”
- java程序中不能包含 全角字符 ,但 字符串中和注释中可以
4注释的字符必须合法
- 大部分情况,编译器会直接忽略掉注释部分,例外:要求注释部分为合法字符,Java允许直接使用\uXXXX形式来表示字符,其中X必须为0~F间的字符
- // \unit5\5.4\Hello.javaInvalid unicode
5. 转义字符: Java对待转义字符的处理:直接替换成对应的字符
- 慎用Unicode转义形式
- System.out.println("abc\u000a".length());String literal is not properly closed by a double-quote 因为\u000a表示一个换行符
- 中止行注释的
- // \u000a代表一个换行符 ,会造成错误:代表一个换行符 cannot be resolved to a type
6. 泛型可能引起的错误
- 如果使用带泛型声明的类时没有传入类型实参,那么这个类型参数默认是声明该参数时指定的第一个上限类型,这个类型参数也被称为raw type(原始类型)
- 原始类型带来的擦除
- 当把一个具有泛型信息的对象赋给另一个没有泛型信息的变量时,所有尖括号之间的类型信息都将被丢弃。例:讲一个List<String>类型的对象转为List,则该List对集合元素的类型检查变成了类型变量的上限(即 Object)
package test1; import java.util.ArrayList;
import java.util.List; public class Test<T extends Number> {
T size;
public Test(){}
public Test(T size){
this.size = size;
}
public T getSize() {
return size;
}
public void setSize(T size) {
this.size = size;
}
public List<String> getStrings(){
List<String> list = new ArrayList<>();
for (int i = 0; i < 3; i++) {
list.add(new Test<Integer>(10 * i).toString());
}
return list;
} public static void main(String[] args) {
Test<Integer> test1 = new Test<>(6);
for (String string : test1.getStrings()) {
System.out.println(string);
} Test test2 = test1;
//test2.getStrings()方法中List<String>的String也会丢失;因此是所有尖括号中的泛型信息都会丢失
for (String string : test2.getStrings()) {//Type mismatch: cannot convert from element type Object to String
System.out.println(string);
} }
}
7. 正则
- split()方法中传入的是正则,正则中“.”匹配任何字符,故需要对其转义 str.split("\\.");
- ps:"\" <mine>
- 字符串中、正则中的“\”都表示各自的转义,要用真正的斜线“\”时,需要用"\\"表示。两者均是如此
- Java中又是用字符串来表示正则,故表示正则中的斜线时,需要用“\\\\”前两个斜线表示正则中的第一个斜线,后两个代表第二个
- (\\)(\\)即是(\)(\),因为字符串中表示斜线,需要用\\。另,各自的转义符\是各自的,正则不能利用字符串的转义符,正则的转义符在字符串看来就是一个“\”,两者互不干扰,只是可以互相表示
- ——> 方法:先写出来普通的正则表达式,在Java的字符串中用“\\”将正则表达式的斜杠一一表示出来就可以了,有几个就替换几次
- 例:正则:\d Java中字符串“\\d”,即“(\\)d”的意思;正则:\\ 字符串“\\\\”,即“(\\)(\\)”;正则:\\\d,字符串“\\\\\\d”,即“(\\)(\\)(\\)d”
8. 多线程
- start()方法启动线程,而不是run()方法
- 静态同步方法的同步监视器为 当前类本身(类对象)
- 分析一个程序不能仅仅停留在静态的代码上,而是应该从程序执行过程来把握程序的运行细节
No.5 表达式中的陷阱的更多相关文章
- Java进阶4表达式中的陷阱
Java进阶4表达式中的陷阱 20131103 表达式是Java中最基本的组成单元,各种表达式是Java程序员最司空见惯的内容,Java中的表达式并不是十分的复杂,但是也有一些陷阱.例如当程序中使用算 ...
- 编写高质量代码改善C#程序的157个建议——建议38:小心闭包中的陷阱
建议38:小心闭包中的陷阱 先看一下下面的代码,设想一下输出的是什么? static void Main(string[] args) { List<Action> lists = new ...
- 关于Linq中的Lambda表达式中OrderBy的深入理解
起因:就是一段Linq语句,OrderBy里面的i是什么? IQueryable<Student> slist = (from s in EFDB.Student select s). O ...
- EL表达式中fn函数 (转载)
JSTL 使用表达式来简化页面的代码,这对一些标准的方法,例如bean的getter/setter方法,请求参数或者context以及 session中的数据的访问非常方便,但是我们在实际应用中经常需 ...
- java、el表达式中保留小数的方法
Java中: import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.NumberFormat; p ...
- ADO.NET+Access: 1,标准表达式中数据类型不匹配
ylbtech-Error-ADO.NET+Access: 1,标准表达式中数据类型不匹配. 1.A,错误代码返回顶部 1,标准表达式中数据类型不匹配. 1.B,出错原因分析返回顶部 未解决 1. ...
- EL表达式中如何截取字符串
EL表达式中如何截取字符串 可以截取,用fn函数:<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/ ...
- ASP.NET MVC 解决LINQ表达式中的SqlMethods 未找到命名空间问题
右键项目属性下的引用: 添加引用: 搜索寻找——System.Data.Linq,然后添加成功,即可解决LINQ表达式中的SqlMethods 未找到命名空间问题
- Lambda 表达式中的变量范围
delegate bool D(); delegate bool D2(int i); class Test { D del; D2 del2; public void TestMethod(int ...
随机推荐
- 树上莫队 wowow
构建:像线性的莫队那样,依旧是按sqrt(n)为一块分块. int dfs(int x){ ; dfn[x]=++ind; ;i<=;i++) if (bin[i]<=deep[x]) f ...
- PlayerPrefs类
该类用于本地持久化保存与读取数据工作原理是:以键值对的形势将数据保存在文件中.该类可以保存与读取3种基本的数据类型,它们是浮点型.整型和字符串型,涉及的方法如下.SetFloat():保存浮点类型Se ...
- 智能卡安全机制比较系列(六) TimeCOS
TimeCOS是握奇公司推出的智能卡操作系统,也可以说是国内早期自己开发的为数不多的几款COS之一.当然随着后来国内公司对于CPU卡开发的投入,其他公司的COS产品也纷纷推出. 其实从握奇的TimeC ...
- Powershell ForEach-Object 循环
Powershell管道就像流水线,对于数据的处理是一个环节接着一个环节,如果你想在某一环节对流进来的数据逐个细致化的处理,可是使用ForEach-Object,$_ 代表当前的数据. 对管道对象逐个 ...
- 文本编辑BOM标记(Byte Order Mark)
微软的自带记事本程序notepad.exe会给UTF-8编码的文件头加入三个隐藏的字节(即BOM).这是一种很愚蠢的做法.就是为了让编辑器不去猜测文件本身是ASCII码还是UTF-8. 什么是BOM ...
- VC的话有必要认真听,但却不用急着照办
本文来自著名风险投资人 Fred Wilson 的博客 AVC,他在 2016 年 8 月 23 日的这篇文章<Understanding VCs>里用简单的语言揭秘了 VC(风险投资人) ...
- Tracing JIT
在一个从Java源码编译到JVM字节码的编译器(如javac.ECJ)里,一个“编译单元”(CompilationUnit)指的是一个Java源文件.而在Dalvik VM的JIT里也有一个结构体名为 ...
- Linux Shell逻辑运算符和表达式详解
Shell 逻辑运算符涉及以下几种类型,只要适当选择,可以解决我们很多复杂的判断,达到事半功倍效果. 一.逻辑判断1.关于文件与目录的逻辑判断-f 常用.判断『文件』是否为普通文件,比如: if [ ...
- jQuery手机触屏左右滑动切换焦点图特效代码
原文地址:http://www.17sucai.com/pins/4857.html 演示地址:http://www.17sucai.com/pins/demoshow/4857 干净演示地址:htt ...
- socket pro
/etc/exports/tmp目录共享为任何人可以共享并可以进行读写操作 /tmp *(rw,no_root_squash) /home/test 192.168.1.*(rw) *(ro) /et ...