- 泛型(Generics)--为集合(collections)提供编译时类型安全,无需每刻从Collections取得一个对象就进行强制转换(cast)
通过引入泛型,我们将获得编译时类型的安全和运行时更小地抛出ClassCastExceptions的可能。在JDK1.5中,你可以声明一个集合将接收/返回的对象的类型。在JDK1.4中,创建雇员名字的清单(List)需要一个集合对象,像下面的语句:
在JDK1.5中,你将使用下面语句ArrayList al=new ArrayList();
如果你试图插入非string类型的值,你将在编译时发现并且修正这类问题。没有泛型,你会发现这样一个bug,当你的客户调用后会告诉你,你所编写的程序抛出ClassCastException异常而崩溃。ArrayList<String> al=new ArrayList<String>();
另外,当你从集合中得到一个元素时你无需进行强制转换。故原先为:
而下面的语句将比上面的更加简单:String employeeName = ((String) listOfEmployee.get(i));
不清楚对象的类型而强制转换对象是不合理的,并且更重要的是,它将在运行时失败。假使用户无意间传入一个包含string buffers类型而非string类型的集合,那结果会怎样呢。在example A中,客户被要求传入一个编译器无法强制的strings类型集合。example B中显示了同样的方法使用泛型是如何实现的。String employeeName = listOfEmployee.get(i);
example A
example BArrayList al=new ArrayList(); al.add("java01"); al.add("java02"); al.add("java01"); al.add("java03"); al.add("java01"); al.add("java04"); al.add("java01"); al.add("java05"); al.add("java01"); Iterator it=al.iterator(); while(it.hasNext()) { String str=(String)it.next(); System.out.println(str); }
ArrayList<String> al=new ArrayList<String>(); al.add("java01"); al.add("java02"); al.add("java01"); al.add("java03"); al.add("java01"); al.add("java04"); al.add("java01"); al.add("java05"); al.add("java01"); Iterator<String> it=al.iterator(); while(it.hasNext()) { String str=it.next(); System.out.println(str); }
现在,通过方法签名可以清楚知道输入集合必须只能包含strings。如果客户试图传入一个包含string buffers的集合,程序将不会编译。同时注意,该方法不包含任何强制转换。它只需要短短一行,一旦你习惯泛型后,它也更加清晰。
而且,你也可以定义自己的泛型类:
public class Generic { public static void main(String[] args) { // TODO Auto-generated method stub //泛型定义在类上 Demo<String> demo=new Demo<String>(); demo.show("泛型定义在类上"); demo.print("泛型定义在类上"); Demo<Integer> d=new Demo<Integer>(); d.show(new Integer(6)); d.print(new Integer(66)); //泛型定义在方法上 Demo1 d2=new Demo1(); d2.show("泛型定义在方法上"); d2.show(new Integer(2)); } } //把泛型定义在类上 class Demo<T> { public void show(T t){ System.out.println("show:"+t); } public void print(T t){ System.out.println("Print:"+t); } } //也可以把泛型定义在方法上 class Demo1{ public <T> void show(T t){ System.out.println("SHow:"+t); } } //泛型也可定义在接口上 interface Inter<T>{ void show(T t); }
- 高级(增强)for
import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; /*高级for循环 格式: for(数据类型 变量名 :被遍历的集合(Collection)或者数组) { } 对集合进行遍历。只能获取集合元素,但是不能对集合进行操作。 传统for于高级for的区别: 高级for有一个局限性,必须要有被遍历的目标 建议在遍历数组时,还是希望使用传统for,因为传统for可以定义角标 */ public class ForEachDemo { public static void main(String[] args) { // TODO Auto-generated method stub ArrayList<String> al=new ArrayList<String>(); al.add("java01"); al.add("java02"); al.add("java03"); //高级for遍历 for(String s:al){ System.out.println(s); } //普通迭代 Iterator<String> it=al.iterator(); while(it.hasNext()) { System.out.println(it.next()); } //高级for对数组遍历 int arr[]={3,5,6}; for(int i:arr) { System.out.println("i:"+i); } HashMap<Integer, String> hm=new HashMap<Integer,String>(); hm.put(1, "a"); hm.put(2, "b"); hm.put(3, "c"); Set<Integer> keySet=hm.keySet(); //高级for替代迭代 for(Integer i:keySet) { System.out.println(i+"::"+hm.get(i)); } //高级for替代迭代 for(Map.Entry<Integer, String> me:hm.entrySet()) { System.out.println(me.getKey()+"---"+me.getValue()); } } }
- 可变参数
public class ParamMethodDemo { public static void main(String[] args) { // TODO Auto-generated method stub show("HelloWOrld!"); show("Hello",1); show("world",1,2,3,4,5,6,7,8,9); } /*JDK1.5版本新特性:可变参数 其实就是数组参数的简写形式。 不用每一次都手动的建立数组对象。 隐式将这些参数封装成了数组。 */ /* 方法的可变参数。 使用注意事项:可变参数一定要定义在参数列表最后面。 */ public static void show(String str,int ...arr) { System.out.println(str+"..."+arr.length); } }
- 静态导入
import java.util.*; import static java.util.Arrays.*;//导入的是Arrays这个类中的所有静态成员。 public class StaticImport { public static void main(String[] args) { // TODO Auto-generated method stub int []arr={3,1,5}; /*静态导入前调用方法的写法 Arrays.sort(arr); int index=Arrays.binarySearch(arr, 1); System.out.println(Arrays.toString(arr)); System.out.println("index="+index);*/ //静态导入后的写法 sort(arr); int index=binarySearch(arr, 1); /*当类名重名时,需要指定具体的报名 当方法重名时,需要指定所属的对象或者类*/ System.out.println(Arrays.toString(arr)); System.out.println("index="+index); } }
- 枚举
枚举是一种特殊的类,其中的每个元素都是该类的一个实例对象,例如可以调用WeekDay.SUN.getClass().getName和WeekDay.class.getName()
枚举类的一些方法:values,valueOf,name,toString,ordinal等方法。
import java.util.Arrays;
public class EnumTest {
public static void main(String[] args) {
WeekDay weekDay2=WeekDay.FRI;
System.out.println("--------------------------------");
System.out.println(weekDay2);
//自己默认的方法
//名字
System.out.println(weekDay2.name());
//顺序,是第几号
System.out.println(weekDay2.ordinal());
System.out.println(weekDay2.valueOf("SUN"));
//weekDay2.values();返回的是一个数组
System.out.println(Arrays.toString(weekDay2.values()));
}
//定义内部类, 枚举类
public enum WeekDay{
SUN(2),MON(1),TUE(2),WED(2),THI(3),FRI,SAT;
//1.构造方法必须定义在元素列表之后
//2.构造方法必须是私有的
private WeekDay(){
System.out.println("first");
}
private WeekDay(int day){
System.out.println("second");
}
}
//内部类
public enum TrafficLamp{
RED(30) {
@Override
public TrafficLamp nextLamp() {
// TODO Auto-generated method stub
return GREEN;
}
},
GREEN(45) {
@Override
public TrafficLamp nextLamp() {
// TODO Auto-generated method stub
return YELLOW;
}
},
YELLOW (5){
@Override
public TrafficLamp nextLamp() {
// TODO Auto-generated method stub
return RED;
}
};
//定义一个抽象方法
public abstract TrafficLamp nextLamp();
private int time;
private TrafficLamp(int time){
this.time=time;
}
}
}