高校网站建设要点,做承兑 汇票一般会用哪些网站,通化市建设局网站,wordpress数据库更改密码编译期处理#xff08;语法糖#xff09;
java编译器把.java源码编译成.class字节码的过程#xff0c;自动生成和转换的一些代码。
默认构造器
public class Candy01 {
}编译成class后的代码
public class Candy1 {public Candy1(){super();}
}自动拆装箱#xff08;jd…编译期处理语法糖
java编译器把.java源码编译成.class字节码的过程自动生成和转换的一些代码。
默认构造器
public class Candy01 {
}编译成class后的代码
public class Candy1 {public Candy1(){super();}
}自动拆装箱jdk5加入
public class Candy02 {public static void main(String[] args) {/*** jdk5之前* Integer x Integer.valueOf(1);* int y x.intValue();*/Integer x 1; // 自动拆箱int y x; // 自动装箱}
}泛型集合取值
public class Candy03 {public static void main(String[] args) {ListInteger list new ArrayList();list.add(10); // 实际调用List.add(Object e)Integer x list.get(0); // 实际调用的是 Object obj List.get(int idx);}
}编译器在获取真正字节码时需要额外做一个类型转换的操作
Integer x (Integer)list.get(0);可变参数
public class Candy04 {public static void foo(String... args) {String[] array args;System.out.println(array);}public static void main(String[] args) {foo(hello, world);}
}编译后的代码
public class Candy04 {public static void foo(String[] args) {String[] array args;System.out.println(array);}public static void main(String[] args) {foo(new String[]{hello, world});}
}如果调用了foo()则等价于foo(new String[]{})创建了一个空数组而不会直接传null进去 数组 - foreach循环
public class Candy05_01 {public static void main(String[] args) {int[] array {1, 2, 3, 4, 5};for(int e : array) {System.out.println(e);}}
}会被编译为
int[] array new int[]{1, 2, 3, 4, 5};
for(int i 0; i array.length; i) {int e array[i];System.out.println(e);
}List - foreach循环
public class Candy05_02 {public static void main(String[] args) {ListInteger list Arrays.asList(1, 2, 3, 4, 5);for(Integer i : list) {System.out.println(i);}}
}会被编译成
Iterator it list.iterator();
while(it.hasNext()) {Integer e (Integer) it.next();System.out.println(e);
}foreach循环写法可以配合数组以及所有实现了Iterator接口的集合类一起使用 switch - 字符串
public class Candy06_01 {public static void choose(String str) {switch(str) {case hello: {System.out.println(h);break;}case world: {System.out.println(w);break;}}}
}会被编译成
public class Candy06_01 {public static void choose(String str) {byte x -1;switch(str.hashCode()) {case 99162322: // hello的hash值if (str.equals(hello)) {x 0;}break;case 113318802: // world的hash值if (str.equals(world)) {x 1;}}switch(x) {case 0:System.out.println(h);break;case 1:System.out.println(w);}}
}编译后其实是执行了两次switch 第一次是根据hash和equals将字符串转换为相应的byte类型第二次才是利用byte进行比较。 第一遍使用hashCode进行比较是为了提高效率较少可能的比较而equals是为了防止hash冲突。 switch - 枚举类
enum Sex {MALE, FEMALE
}
public class Candy06_02 {public static void foo(Sex sex) {switch(sex) {case MALE: {System.out.println(男);break;}case FEMALE: {System.out.println(女);break;}}}
}编译后代码
public class Candy06_02 {public static void foo(Sex sex) {// 获取枚举的序号MALE.ordinal() 0, FEMALE.ordinal() 1int ordinal sex.ordinal(); switch (ordinal) {case 0: // MALESystem.out.println(男);break;case 1: // FEMALESystem.out.println(女);break;}}
}枚举类
enum Sex {MALE, FEMALE
}转换后代码
public final class Sex extends java.lang.EnumSex {// 枚举常量public static finalpublic static final Sex MALE;public static final Sex FEMALE;// 私有构造函数enum 不能外部实例化private Sex(String name, int ordinal) {super(name, ordinal);}// 静态初始化块初始化所有枚举值static {MALE new Sex(MALE, 0);FEMALE new Sex(FEMALE, 1);$VALUES new Sex[]{MALE, FEMALE};}// 自动生成的方法values() 返回所有枚举值public static Sex[] values() {return (Sex[])$VALUES.clone();}// 自动生成的方法valueOf(String) 根据名字返回枚举public static Sex valueOf(String name) {return (Sex)Enum.valueOf(Sex.class, name);}// 内部存储所有枚举值的数组private static final Sex[] $VALUES;
}try-with-resources简化资源关闭
public class Candy07 {public static void main(String[] args) {/*try(资源变量 创建资源对象) {}catch() {}*/try(InputStream is new FileInputStream(d:\\test.txt)) {System.out.println(is);}catch (Exception e) {e.printStackTrace();}}
}其中资源对象需要实现AutoCloseable接口例如InputStream、OutPutStream、Connection、Statement、ResultSet等接口都实现了AutoCloseable接口使用try-with-resources可以不用写finally语句编译器会帮助我们生成资源关闭的代码。 上边代码被编译为
public class Candy07 {public static void main(String[] args) {try {InputStream is new FileInputStream(d:\\test.txt);Throwable t null;try {System.out.println(is);}catch (Throwable e1){t e1; // t是我们代码中出现的异常throw e1;} finally {// 判断了资源不为空if(is ! null) {// 如果我们的代码有异常if(t ! null) {try {is.close();} catch (Throwable e2) {// 如果close出现异常作为被压制异常添加t.addSuppressed(e2);}}else {// 如果代码没有异常close出现的异常就是最后catch块中的eis.close();}}}}catch (IOException e) {e.printStackTrace();}}
}如果我们的代码出现了异常并且关闭资源的时候又出现了异常如果想让这两个异常都显示可以使用压制异常。 例如
public class Candy08 {public static void main(String[] args) {try (MyResource resource new MyResource()) {int i 1 / 0; // 除0异常}catch (Exception e) {e.printStackTrace();}}
}
class MyResource implements AutoCloseable {Overridepublic void close() throws Exception {throw new Exception(close异常); // 资源关闭异常}
}输出 两个异常都会被抛出 方法重写时的桥接方法
class A {public Number m() {return 1;}
}
class B extends A {Override// 子类m方法的返回值是Integer是父类m方法返回值Number的子类public Integer m() {return 2;}
}编译后的代码
class B extends A {public Integer m() {return 2;}// 此方法才是真正重写了父类public Number m()方法public synthetic bridge Number m() {// 调用public Integer m()return m();}
}桥接方法比较特殊只对java虚拟机可见与原来的public Integer m()没有命名冲突。 无参的匿名内部类
public class Candy08 {public static void main(String[] args) {Runnable runnable new Runnable() {Overridepublic void run() {System.out.println(ok);}};}
}编译后代码
// 额外生成的类
final class Candy08$1 implements Runnable {Candy08$1() {}Overridepublic void run() {System.out.println(ok);}
}
public class Candy08 {public static void main(String[] args) {Runnable runnable new Candy08$1();}
}引用局部变量的匿名内部类
public class Candy10 {public static void test(final int x) {Runnable runnable new Runnable() {public void run() {System.out.println(x);}};}
}编译后
// 额外生成的类
final class Candy10$1 implements Runnable {int val$x;Candy10$1(int x) {this.val$x x;}public void run() {System.out.println(this.val$x);}}
public class Candy10 {public static void test(final int x) {Runnable runnable new Candy10$1(x);}
}这也解释了为什么匿名内部类里边使用的变量必须使用final修饰因为在创建Candy10$1对象时将x的值赋值给了Candy10$1对象的val$x属性所以x的值不会在发生变化了。如果发生变化那么val$x属性没有机会再跟着一起变化了。