1、静态导入: **import语句可以导入一个类或某个包中的所有类 **import static语句导入一个类中的某个静态方法或所有静态方法 静态导入后,静态方法前面就不用写类名.方法的方式类调用 **语法举例: import static java.lang.Math.sin;//导入一个静态方法 import static java.lang.Math.*; //导入一个类中的所有静态方法 **静态导入使用注意: 当类名重复时,需要制定具体的包名; 当方法重名时,需要制定具体所属的对象或者类
2、可变参数:**可变参数的特点:*可变参数只能出现在参数列表的最后;*...位于变量类型和变量名之间,前后有无空格都可以;*调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中以数组的形式访问可变参数。**可变参数举例:*变量类型... 变量名 如 int... arr 表示可变参数数组*public static void show(String str , int... arr){}
3、增强for循环:**语法:for ( type 变量名:集合变量名 ) { … }**注意事项:迭代变量必须在( )中定义!集合变量可以是数组或实现了Iterable接口的集合类**举例:public static int add(int x,int ...args) {int sum = x;for(int arg:args) {sum += arg;}return sum;}**增强for循环代替了迭代器使用的不爽,简化书写**增强for循环局限性:对集合或者数组进行遍历时,只能取元素,不能对集合进行操作
4、基本数据类型的自动装箱和拆箱**基本数据类型byte ---> Byteshort ---> Shortint ---> Integerlong ---> Longfloat ---> Floatdouble ---> Doublechar ---> Characterboolean ---> Boolean**例子:**装箱:自动把一个基本数据类型的数据装箱成一个该类型数据的对象引用Integer i = 3;(jdk1.5之前这样写是不行的,编译报错)**拆箱:自动把一个基本数据类型的对象引用拆箱成一个基本数据类型的数据,再参与运算Integer i = 12;sop(i+4);**享元模式:Integer num1 = 12;Integer num2 = 12;System.out.println(num1 == num2);//打印trueInteger num5 = Integer.valueOf(12);Integer num6 = Integer.valueOf(12);System.out.println(num5 == num6);//打印trueInteger num3 = 129;Integer num4 = 129;System.out.println(num3 == num4);//打印false为什么前面的返回true而后面的运算返回false呢?对于基本数据类型的整数,装箱成Integer对象时,如果该数值在一个字节内,(-128~127),一旦装箱成Integer对象后,就把它缓存到磁里面,当下次,又把该数值封装成Integer对象时会先看磁里面有没有该对象,有就直接拿出来用,这样就节省了内存空间。因为比较小的整数,用的频率比较高,就没必要每个对象都分配一个内存空间。这就是享元模式!比如26个英文字母,10个阿拉伯数字
5、枚举**为什么要有枚举?问题:要定义星期几或性别的变量,该怎么定义?假设用1-7分别表示星期一到星期日,但有人可能会写成i荏鱿胫协nt weekday = 0;或即使使用常量方式也无法阻止意外。枚举就是要让某个类型的变量的取值只能为若干个固定值中的一个,否则,编译器就会报错。枚举可以让编译器在编译时就可以控制源程序中填写的非法值,普通变量的方式在开发阶段无法实现这一目标。**用普通类如何实现枚举的功能?定义一个Weekday类来模拟实现:步骤:*私有化构造方法*每个元素分别用一个公有的静态成员变量表示(public static final)*可以有若干公有方法或抽象方法。采用抽象方法定义nextDay就将大量的if.else语句转移成了一个个独立的类。**枚举的应用:举例:定义一个Weekday的枚举。扩展:枚举类的values,valueOf,name,toString,ordinal等方法 (记住,讲课时要先于自定义方法前介绍,讲课更流畅)总结:枚举是一种特殊的类,其中的每个元素都是该类的一个实例对象。 例如可以调用WeekDay.SUN.getClass().getName和WeekDay.class.getName()。**枚举的高级应用:**枚举就相当于一个类,其中也可以定义构造方法、成员变量、普通方法和抽象方法。**枚举元素必须位于枚举体中的最开始部分,枚举元素列表的后要有分号与其他成员分隔。把枚举中的成员方法或变量等放在枚举元素的前面,编译器报告错误。**带构造方法的枚举构造方法必须定义成私有的如果有多个构造方法,该如何选择哪个构造方法?枚举元素MON和MON()的效果一样,都是调用默认的构造方法。**带方法的枚举定义枚举TrafficLamp实现普通的next方法实现抽象的next方法:每个元素分别是由枚举类的子类来生成的实例对象,这些子类采用类似内部类的方式进行定义。增加上表示时间的构造方法 **枚举只有一个成员时,就可以作为一种单例的实现方式。
6、泛型:**泛型是提供给javac编译器使用的,可以限定集左佯抵盗合中的输入类型,让编译器挡住源程序中的非法输入,编译器编译带类型说明的集合时会去除掉“类型”信息,使程序运行效率不受影响,对于参数化的泛型类型,getClass()方法的返回值和原始类型完全一样。由于编译生成的字节码会去掉泛型的类型信息,只要能跳过编译器,就可以往某个泛型集合中加入其它类型的数据,例如,用反射得到集合,再调用其add方法即可。**ArrayList<E>类定义和ArrayList<Integer>类引用中涉及如下术语:整个称为ArrayList<E>泛型类型ArrayList<E>中的E称为类型变量或类型参数整个ArrayList<Integer>称为参数化的类型ArrayList<Integer>中的Integer称为类型参数的实例或实际类型参数ArrayList<Integer>中的<>念着typeofArrayList称为原始类型**参数化类型与原始类型的兼容性:参数化类型可以引用一个原始类型的对象,编译报告警告,例如,Collection<String> c = new Vector();//可不可以,不就是编译器一句话的事吗?原始类型可以引用一个参数化类型的对象,编译报告警告,例如,Collection c = new Vector<String>();//原来的方法接受一个集合参数,新的类型也要能传进去**参数化类型不考虑类型参数的继承关系:Vector<String> v = new Vector<Object>(); //错误!///不写<Object>没错,写了就是明知故犯Vector<Object> v = new Vector<String>(); //也错误!编译器不允许创建泛型变量的数组。即在创建数组实例时,数组的元素不能使用参数化的类型,例如,下面语句有错误:Vector<Integer> vectorList[] = new Vector<Integer>[10];**泛型限定:**限定通配符的上边界:正确:Vector<? extends Number> x = new Vector<Integer>();错误:Vector<? extends Number> x = new Vector<String>();**限定通配符的下边界:正确:Vector<? super Integer> x = new Vector<Number>();错误:Vector<? super Integer> x = new Vector<Byte>();**提示:限定通配符总是包括自己。?只能用作引用,不能用它去给其他变量赋值Vector<? extends Number> y = new Vector<Integer>();Vector<Number> x = y;上面的代码错误,原理与Vector<Object > x11 = new Vector<String>();相似,只能通过强制类型转换方式来赋值。