《Java5.0新特性》
四大点(枚举、泛型、注释、..);5 小点(包装类、静态应用、可变长参数、for-each、..)
一、自动装箱 和 自动解箱技术
装箱Autoboxing,也翻译作 封箱;解箱Unautoboxing(也译作 解封)
1、自动装箱技术:编译器会自动将简单类型转换成封装类型。
2、编译器会自动将封装类型转换成简单类型
3、注意:自动装箱和自动解箱只会在必要的情况下执行。
int 能隐式提升成 long;但Integer不能隐式提升成Long,只能提升成Number
封装之后就成类,只能由子类转成父类;而Integer和Long是Number的不同子类。
如: int i; short s; Integer II; Short SS;
可以 i=SS; 但不可以 II=s; //赋值时,右边的数先转成左边数的对应类型,再进行隐式类型提升
二、静态引用概念:
用 import static 节省以后的书写。
引入静态属性 import static java.lang.System.out;
引入静态方法 import static java.lang.Math.random;
import static 只能引入静态的方法或属性;不能只引入类或非静态的方法。
如:import static java.lang.System.*;
out.println(“a”); //等于System.out.println("a"); 由于out是一个字段,所以不能更节省了
如果 import static java.lang.System.gc; 则可以直接在程序中用 gc(); //等于System.gc();
三、可变长参数
一个方法的参数列表中最多只能有一个可变长参数,而且这个变长参数必须是最后一个参数
方法调用时只在必要时去匹配变长参数。
/**********变长参数的例子*************************************/
import static java.lang.System.*;//节省书写,System.out直接写out
public class TestVararg {
public static void main(String... args){
m();
m("Liucy");
m("Liucy","Hiloo");
}
static void m(String... s){out.println("m(String...)");}
//s可以看作是一个字符串数组String[] s
static void m(){out.println("m()");}
static void m(String s){out.println("m(String)");}
} //m(String... s) 是最后匹配的
/**********************************************************/
四、枚举 enum
1、定义:枚举是一个具有特定值的类型,对用户来说只能任取其一。
对于面向对象来说时一个类的对象已经创建好,用户不能新生枚举对象,只能选择一个已经生成的对象。
2、枚举本质上也是一个类。枚举值之间用逗号分开,以分号结束(如果后面没有其他语句,分号可不写)。
3、枚举分为两种:类型安全的枚举模式和类型不安全的枚举模式
4、枚举的超类(父类)是:Java.lang.Enum。枚举是 final 类所以不能继承或被继承。但可以实现接口。
枚举中可以写构造方法,但构造方法必需是私有的,而且默认也是 私有的 private
5、一个枚举值实际上是一个公开静态的常量,也是这个类的一个对象。
6、枚举中可以定义抽象方法,但实现在各个枚举值中(匿名内部类的方式隐含继承)
由于枚举默认是 final 型,不能被继承,所以不能直接用抽象方法(抽象方法必须被继承)
在枚举中定义抽象方法后,需要在自己的每个枚举值中实现抽象方法。
枚举是编译期语法,编译后生成类型安全的普通类
values()静态方法,返回枚举的元素数组
name方法
/**********************************************************/
final class Season1{ //用 final 不让人继承
private Season1(){} //用 private 构造方法,不让人 new 出来
public static final Season1 SPRING=new Season1("春");
public static final Season1 SUMMER=new Season1("夏");
public static final Season1 AUTUMN=new Season1("秋");
public static final Season1 WINTER=new Season1("冬");
String name; //将"春夏秋冬"设为本类型,而不是24种基本类型,为防止值被更改
private Season1(String name){
this.name=name;
}
public String getName(){
return this.name;
}}
/********上面是以前版本时自定义的枚举,下面是新版的枚举写法********/
enum Season2{
SPRING("春"), SUMMER("夏"), AUTUMN("秋"), WINTER("冬");
String name;
Season2(String name){ this.name=name; }
public String getName(){return this.name;}
}//注意:枚举类是有序的;如:Season2.SPRING.ordinal()
/**********************************************************/
/*******关于枚举的例子****************************************/
import static java.lang.System.*;
public class TestTeacher {
public static void main(String[] args) {
for(TarenaTeacher t:TarenaTeacher.values()){
t.teach();
}}}
enum TarenaTeacher{
LIUCY("liuchunyang"){void teach(){out.println(name+" teach UC");}},
CHENZQ("chenzongquan"){void teach(){out.println(name+" teach C++");}},
HAIGE("wanghaige"){void teach(){out.println(name+" teach OOAD");}};
String name;
TarenaTeacher(String name){this.name=name;}
abstract void teach();
}
/**********************************************************/
enum Animals {
DOG ("WangWang") , CAT("meow") , FISH("burble");
String sound;
Animals ( String s ) { sound = s; }
}
class TestEnum {
static Animals a;
public static void main ( String[] args ) {
System.out.println ( a.DOG.sound + " " + a.FISH.sound );
}}
/**********************************************************/
五、新型 for 循环 for—each,用于追求数组与集合的遍历方式统一
1、数组举例:
int[] ss = {1,2,3,4,5,6};
for(int i=0; i<ss.length; i++){
System.out.print(ss[i]);
} //以上是以前的 for 循环遍历,比较下面的for—each
System.out.println();
for(int i : ss){
System.out.print(i);
2、集合举例:
List ll = new ArrayList();
for(Object o : ll ){
System.out.println(o);
}
注:凡是实现了java.lang.Iterable接口的类就能用 for—each遍历
用 for—each时,不能用list.remove()删除,因为他内部的迭代器无法调用,造成多线程出错。
这时只能用 for 配合迭代器使用。
六、泛型 Generic
1、为了解决类型安全的集合问题引入了泛型。
泛型是编译检查时的依据,也是编译期语法。
(编译期语法:编译期有效,编译后擦除,不存在于运行期)
2、简单的范型应用:集合(ArrayList, Set, Map, Iterator, Comparable)
List<String> l = new ArrayList<String>();
<String>:表示该集合中只能存放String类型对象。
3、使用了泛型技术的集合在编译时会有类型检查,不再需要强制类型转换。
String str = l.get(2); //因为List<String> l, 所以 Error
注:一个集合所允许的类型就是这个泛型的类型或这个泛型的子类型。
4、List<Number> l = new ArrayList<Integer> //Error
List<Integer> l = new ArrayList<Integer> //Right
必须类型一致,泛型没有多态
5、泛型的通配符<?>
泛型的通配符表示该集合可以存放任意类型的对象。但只有访问,不可以修改。
static void print( Cllection<?> c ){
for( Object o : c )
out.println(o);
}
6、带范围的泛型通配符
泛型的声明约定T表示类型,E表示元素
(1)、上界通配符,向下匹配:<? extends Number> 表明“extends”或“implements”,认为是 final 的
表示该集合元素可以为Number类型及其子类型(包括接口),例如 Number,Integer,Double
此时集合可以进行访问但不能修改。即不允许调用此对象的add,set等方法;但可以使用 for-each 或 get.
(2)、下界通配符,向上匹配:<? super Number>
表示该集合元素可以为Number类型及其父类型,直至 Object。
可以使用 for-each,add,addAll,set,get等方法
(3)、接口实现:<? extends Comparable>
表示该集合元素可以为实现了Comparable接口的类
7、泛型方法
在返回类型与修饰符之间可以定义一个泛型方法,令后面的泛型统一
这里只能用 extends 定义,不能用 super ;后面可以跟类(但只能有一个,且要放在首位)其余是接口
符号只有 & //“&”表示“与”;逗号表示后面的另一部分
静态方法里面,不能使用类定义的泛型,只能用自己定义的;因为静态方法可以直接调用;
所以普通方法可以使用类定义的及自己定义的泛型
public static <T> void copy(T[] array,Stack<T> sta){……}
public static <T,E extends T> void copy (T[] array,Stack<E> sta){…..}
public static <T extends Number&Comparable> void copy(List<T> list,T[] t);
8、不能使用泛型的情况:
(1)、带泛型的类不能成为 Throwable 类和 Exception 类的子类
因为cathc()中不能出现泛型。
(2)、不能用泛型来 new 一个对象
如:T t = new T();
(3)、静态方法不能使用类的泛型,因为静态方法中没有对象的概念。
9、在使用接口的时候指明泛型。
class Student implements Comparable<Student>{…….}
10、泛型类
/********************************************************************/
class MyClass<T>{
public void m1(T t){}
public T m2(){
return null;
}}
/********************************************************************/