介绍以下几种语言特性:
Java5的特性
1.静态引用
2.可变参数
3.自动装箱和拆箱 包装类的缓存设计
4.枚举
一、静态引用(语法糖,不推荐使用,了解一下即可)
先看看普通的引用,就是import
package com.StadyJava.day22; import java.util.Collections; public class LoadResourceDemo { public static void main(String[] args) throws Exception{ Collections.emptyList(); Collections.emptyList(); Collections.emptyList(); Collections.emptyList(); } }
我打Collections.emptyList(); Idea编译器会自动的帮我引用 java.util.Collections
可以看到,我使用了4次emptyList()方法,那么假如我下面还要使用emptyList()很多次,我每次都要写Collections,感觉很麻烦,所以静态引用就出来了,看代码
package com.StadyJava.day22; import static java.util.Collections.*; public class LoadResourceDemo { public static void main(String[] args) throws Exception{ emptyList(); emptyList(); emptyList(); emptyList(); } }
现在我直接写emptyList()就可以了,当做是我自己的方法了。而且通过反编译代码发现,底层还是使用了Collections.emptyList();,所以静态引用就是一个语法糖。
而且容易混淆,也不知道这个方法到底是哪个类的,所以静态引用不要使用,了解一下得了。
二、可变参数 (就是一个语法糖)
该说的没什么说的了,全在代码和注释里面。我写了一个商品类,然后写了一个可变参数类,看看吧
商品类,这里面字段是自己写的,构造器和属性都是使用Generate自己生成的:
package com.StadyJava.day24; public class GoodsDemo { //商品名称,价格和数量 private String name; private Integer price; private Integer number; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getPrice() { return price; } public void setPrice(Integer price) { this.price = price; } public Integer getNumber() { return number; } public void setNumber(Integer number) { this.number = number; } public GoodsDemo() { } public GoodsDemo(String name, Integer price, Integer number) { this.name = name; this.price = price; this.number = number; } }
可变参数类:
package com.StadyJava.day24; public class VarArgsDemo { public static void main(String[] args) { GoodsDemo goodsDemo1=new GoodsDemo("许嵩的专辑",50,1000); GoodsDemo goodsDemo2=new GoodsDemo("林俊杰的专辑",20,1000); GoodsDemo goodsDemo3=new GoodsDemo("蜀云泉的专辑",1,1); //调用可恶的方法1 System.out.println(sum1(goodsDemo1,goodsDemo2,goodsDemo3)); //方法2,创建一个数组来 GoodsDemo [] goodsDemos={goodsDemo1,goodsDemo2,goodsDemo3}; System.out.println(sum2(goodsDemos)); //方法3,试试语法糖好吃不 System.out.println(sum3(goodsDemo1,goodsDemo2,goodsDemo3)); } //我们设计一个方法,求买的东西的价格总和。如果没有可变参数,我们会怎么办? //方法1,写死参数 private static Integer sum1(GoodsDemo arg1,GoodsDemo arg2,GoodsDemo arg3){ return arg1.getPrice()*arg1.getNumber()+arg2.getPrice()*arg2.getNumber()+arg3.getPrice()*arg3.getNumber(); } //方法2,创建一个数组,来存放参数 private static Integer sum2(GoodsDemo[] arg){ Integer msg=0; for (GoodsDemo good:arg) { msg += good.getPrice() * good.getNumber(); } return msg; } //方法3,使用可变参数的方式,其实可变参数的方式,底层还是数组。说白了就是一个语法糖而已。使用方法就是... //注意!!!使用可变参数的方式时,如果有其它的参数,一定要把可变参数放在最后!一定要把可变参数放在最后!!! private static Integer sum3(GoodsDemo ... arg){ Integer msg=0; for (GoodsDemo good:arg) { msg+=good.getPrice()*good.getNumber(); } return msg; } }
三、自动装箱和拆箱 包装类的缓存设计
自动装箱和拆箱我不想讲,还是语法糖。只不过不需要你自己去转换类型了。讲讲包装类的缓存设计。
包装类的缓存设计:
Byte,short,Integer,Long.缓存范围:[-128,127]
Charactor: 缓存范围:[0,127]
在这个范围之内的可以直接拿来使用的,看个代码:
public static void main(String[] args) throws Exception{ //new出来的内存地址都不一样,所以比较的时候一定是false Integer num1=new Integer(17); Integer num2=new Integer(17); System.out.println(num1==num2); //Valueof的底层,-128到127之间是缓存中读取,范围之外的new Integer num3=Integer.valueOf(17); Integer num4=Integer.valueOf(17); System.out.println(num3==num4); //-128到127之间都是true,之外都是false,这个和上面的差不多 Integer num5=17; Integer num6=17; System.out.println(num5==num6); //上面的比较都用==,这里用equals方法,本质就是intValue Integer num7=200; Integer num8=200; System.out.println(num7.equals(num8)); //System.out.println(num7.intValue()==num8.intValue()); }
给你们看看Valueof的底层
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
就是缓存。
四、枚举(语法糖)
讲枚举之前,我们先来看看一个代码例子,一周有7天,我现在要让一个员工输入休息的是哪一天,输出一些内容,用到了3个类,看看
员工类:
package com.StadyJava.day24; public class Employee { private WeekDay restDay; public WeekDay getRestDay() { return restDay; } public void setRestDay(WeekDay restDay) { this.restDay = restDay; } }
员工类就一个周类型的字段和构造
周类:
package com.StadyJava.day24; public class WeekDay { //这个一周7天,写成这种数字的形式,1,2,3,...但是数字这种无法保证别人乱输,所以不要使用数字了 //public Integer Mon=1; public static final WeekDay Mon=new WeekDay(); public static final WeekDay Tue=new WeekDay(); public static final WeekDay Wen=new WeekDay(); public static final WeekDay Thu=new WeekDay(); public static final WeekDay Fri=new WeekDay(); public static final WeekDay Sta=new WeekDay(); public static final WeekDay Sun=new WeekDay(); //我这里设置构造函数为私有的,就不能传入new WeekDay对象了,只能调用我写好的对象 private WeekDay(){} }
这个类,我没有设置int类型的1,2,3...因为在输入的时候,别人可以乱输入数字的,我还得判断。直接设置成这个
调用台:
package com.StadyJava.day24; public class EnumDemo { public static void main(String[] args) { Employee e =new Employee(); //由于这里可以传入new WeekDay()的空对象,所以我把构造函数设置为私有的了 e.setRestDay(WeekDay.Mon); if (e.getRestDay() == WeekDay.Sta||e.getRestDay()==WeekDay.Sun) { System.out.println("周末休息"); } else { System.out.println("周一至周五休息"); } } }
这就是我的调用台代码
这样就可以实现,员工输入自己哪一天休息的,然后输入一些内容。
讲真,WeekDay这个类写起来还是稍微耗时间的,所以有了枚举,我们看看枚举是怎么写的
package com.StadyJava.day24; public enum WeekDay { Mon,Tue,Wen, Thu,Fri, Sta,Sun; }
完事...枚举就是为了解决这个问题而存在的,所以枚举适用的场景就是固定的个数的时候。
枚举底层的代码,经过反编译之后,和 public static final WeekDay Mon=new WeekDay(); 是一样滴,所以枚举也是一个语法糖。