天天看点

每天1个java知识点——java语法糖

泛型擦除:

java中的泛型只在 程序源码中存在, 在编译后的字节码文件中已经替换为原生类型, 并会插入一些强制转换的代码。

T f(T  t) {
    T a = T.getA();
    return a
}
实际上是

T  f(Object t) {
    Object a = (T)t.getA();
    return (T)a;
}
           

即只在会方法的入口 和方法的出口处,做强制转换, 而实际上传入的都是原生类型,可以理解为object

神奇的例子:

public static void method(List<Integer> list) {
    System.out.println("inoke method(List<Integer> list)");
}

public static void method(List<String> list) {
    System.out.println("inoke method(List<String> list)");
}
           

这个编译会报错,认为有2种相同的方法, 因为编译后被擦除了。

然后下面这个例子却是tm能ok的:

public static Integer method(List<Integer> list) {
    System.out.println("inoke method(List<Integer> list)");
}

public static String method(List<String> list) {
    System.out.println("inoke method(List<String> list)");
}

public static void main(){
    method(new ArrayList<String>());
    method(new ArrayList<Integer>());
}
           

解释:

返回值不参与重载的选择,但是因为返回值作为描述符不一致,以至于可以在一个class文件中共存。

必须用Sun JDK1.6才能编译通过

Signature:

用于解决泛型歹来的参数类型的识别问题。

可存储字节码层面的特征签名。

字节码层面: 方法名称、参数顺序、参数类型、 返回值、受检查异常, 这5个决定了1个字节码层面的方法是否唯一。

如果是java语法层面, 则签名只受方法名称、参数顺序、参数类型这3个的影响。

他会保存参数化类型的信息, 即虽然code里都转成了object, 但是其参数化类型还是通过signature保存到了元数据区, 可以通过反射获取参数化类型。

自动装箱拆箱、循环

自动装箱拆箱: 就是在编译后, 自动把装拆箱的地方加上 Integer.valueOf() 或者 包装类型.intValue()

可变参数:被优化成一个数组

Arrays.asList(“1”,“2”,“3”,“4”) => Arrays.asList(new String[]{ “1”, “2”, “3”, “4”})

带iterator接口的 for循环:

for(String str : listStr) {

}

被优化成

for(Interator it = list.iterator(); it.hasNext()) {
    xxx   it.next xxx...
}

Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 321;
Integer f = 321;
Long g = 3L;
           

// true, 小于128,用常量池里的常量比较

System.out.println(c == d);

// false,非常量池,用各自不同的地址比较

System.out.println(e == f );

// true, 同1

System.out.println(c == (a+b));

// true, Integer

System.out.println(c.equals(a+b));

// true, 这个为什么==是可以的,是因为Long小于128时,也会用常量池的值吗

System.out.println(g == (a+b));

// false , equals不处理数据转型的关系。

System.out.println(g.equals(a+b));

条件编译:

if(true) {
xxx
} else {
    yyy
}
           

被优化成了

xxx
           

因为编译器很明确只能走xxx这个分支。

只能用于if+常量

使用常量与其他带有条件判断能力的语句搭配,则会报错

while(false) {
    xxx
}
           

这个会报错unreachable statement code

每天1个java知识点——java语法糖

因为系统检测到这句代码是永远无法到达的分支,直接给你禁掉了

继续阅读