java基础巩固-宇宙第一AiYWM:为了维持生计,JVM_Part8~(Java语法糖)整起

102 阅读3分钟

语法糖(Syntactic Sygar),也叫糖衣语法,是由英国计算机科学家彼得约翰兰达发明的一个术语,指在计算机语言中添加的某种语法,这种语法对语言的功能没影响但是更方便咱们这些码农使用。。(语法糖可以看作编译器实现的用来提升效率的一些小把戏)

  • 泛型与类型擦除:咱们Java还没有泛型时咱们一般就只能通过Object是所有类型的父类类型强制转换两个特点的配合来实现类型泛化在这里插入图片描述
    • 泛型:本质是**参数化类型(也就是所操作的数据类型被指定为一个参数,这种参数类型可用在类、接口和方法的创建中,分别称为泛型类、泛型接口和泛型方法)**的应用。
      • Java中的泛型只在程序源码中存在,在编译后的字节码文件中就已经被替换为原来的原生类型(Raw Type)了,并且在相应的地方插入了强制转型代码。
    • 类型擦除:Java中的泛型实现方法成为类型擦除,基于这种方法实现的泛型也叫伪泛型。 在这里插入图片描述
public static void mian(String[] args){
	Map<String, String> map = new HashMap<String, String>();
	map.put("hhb", "老公");
	map.put("minqaqq", "老婆");
	System.out.println(map.get("hhb"));
	System.out.println(map.get("minqaqq"));
}

这段代码编译后会怎样?(把这段Java代码编译成为Class文件,然后用字节码反编译工具进行反编译后发现泛型都不见了,也就是程序又变回了Java泛型出现之前的写法)

public static void mian(String[] args){
	Map map = new HashMap();
	map.put("hhb", "老公");
	map.put("minqaqq", "老婆");
	System.out.println((String)map.get("hhb"));
	System.out.println((String)map.get("minqaqq"));
}

那为什么要用类型擦除呢,关于原因众说纷纭。如作者所说,通过擦除法来实现泛型丧失了一些泛型的优雅。

  • 当泛型遇见方法重载时,如下图,这两个方法没办法共存在一个.Class文件中 在这里插入图片描述
    • 但是这两个方法,加入了不同的返回值后,方法重载可以成功,这段代码就可以被编译和执行了,因为加了不同的返回值后这俩方法可以共存在一个.Class文件之中 在这里插入图片描述
  • 自动装箱、自动拆箱、遍历循环。继续上面的代码编译前后的故事
    • 包装类的"=="运算在不遇到算术运算时不会自动拆箱
    • equals()方法不处理数据转型的关系
public static void mian(String[] args){
	List<Integer> list = Arrays.asList(1, 2, 3, 4);
	int sum = 0;
	for(int i : list){
		sum += i;
	}
	System.out.println(sum);
}

这段代码编译后会怎样?(把这段Java代码编译成为Class文件,然后用字节码反编译工具进行反编译后发现泛型都不见了,也就是程序又变回了Java泛型出现之前的写法)

  • 自动装箱、自动拆箱在编译之后被转化成为了对应的包装和还原方法
  • 遍历循环则把代码还原成为了迭代器的实现,这也是为何遍历循环需要被遍历的类实现Iterable接口的原因 在这里插入图片描述
  • 变长参数在调用时变成了一个数组类型的参数,在变长参数出现之前,类似功能就也只能用数组完成,落叶归根哪
public static void mian(String[] args){
	List list = Arrays.asList(new Integer[]{
		Integer.valueOf(1);//自动装箱、自动拆箱在编译之后被转化成为了对应的包装和还原方法
		Integer.valueOf(2);//自动装箱、自动拆箱在编译之后被转化成为了对应的包装和还原方法
		Integer.valueOf(3);//自动装箱、自动拆箱在编译之后被转化成为了对应的包装和还原方法
		Integer.valueOf(4);//自动装箱、自动拆箱在编译之后被转化成为了对应的包装和还原方法
	});
	int sum = 0;
	//遍历循环则把代码还原成为了迭代器的实现
	for(Iterator localIterator = list.iterator(); localIterator.hasNext();){
		int i = ((Integer) localIterator.next()).intValue();//自动装箱、自动拆箱在编译之后被转化成为了对应的包装和还原方法
		sum += i;
	}
	System.out.println(sum);
}