您的位置:首页 > 编程语言 > Java开发

Java5.0新特性

2010-04-05 15:59 323 查看
Subject:
Java5.0新特性之(1)-泛型
Description:
Q-1问题引入 提供一个能对任一类型赋值转换的类。
Class ObjectfFoo {
private Object foo;
public void setFoo(Object foo)
{
this.foo=foo;
}
Public Object getFoo()
{
return foo;
}
}
使用:
ObjectFoo foo1=new ObjectFoo();
Foo1.setFoo(new Boolean(true));
Boolean b=(Boolean)foo1.getFoo(); //采用向下类型转,完成从Object->Boolean
分析:若在最后一句,你必须记住set的(Boolean)类型,才能在get中进行正确的类型转换。
如果写成ObjectFoo foo1=new ObjectFoo();
Foo1.setFoo(new Boolean(true));
String b=(String)foo1.getFoo();
在编译期不会犯错,但在运行期会抛出ClassCastException之错。如何解决这个问题,用泛型。
A-1:引入Generic 概念,即如上的Object类型,在类定义时可以不定义要使用的类型,但在使用时(声明该类时)传入相应的类型。
泛型的定义:
Class GenericFoo <T> {
private T foo;
public void setFoo(T foo)
{
this.foo=foo;
}
Public T getFoo()
{
return foo;
}
}
泛型的使用:
GenericFoo<Boolean> foo1=new GenericFoo<Boolean>(); //声明
GenericFoo<Integer> foo2=new GenericFoo<Integer>(); //声明,传入T为Integer
foo1.setFoo(new Boolean(true));
Boolean b=foo1.getFoo();
如果这样使用:foo1.setFoo(new Integer(1)); //编译器会报错,Ingeger参数对GenericFoo<Boolean>是不可接受的。从而就避免了运行期CastType Error
//泛型在使用时,所有类型名出现的地方都要有<T>,告诉编译器这个类是有参数的,参数是T。
// 如果使用了一个泛型,但是并没有指定类型参数<T>,那么编译器会认为T是object。可以传入何类型的参数,但你自己的要做强制类型转换,此时的泛型就退化成非泛型了!
Q-2:泛型数组定义
Class GenericFoo <T> {
private T[] fooArray;
public void setFoo(T[] fooArray)
{
this.fooArray=fooArray;
}
Public T[] getFoo()
{
return fooArray;
}
}
A-2:泛型数组使用
public static void main(String[] args) {
GenericFooArray<String> foo1=new GenericFooArray<String>();
String[] str={"cisco","webex","branding"};
String[] str2=null;

foo1.setFoo(str);
str2=foo1.getFoo();

for(int i=0;i<str2.length;i++)
{
System.out.println(str2[i]);
}
}
Q-3:用泛型概念模拟一个simple collection , 如ArrayList
public class SimpleArrayList<T> {
private T[] objArr;
private int index=0; //the 最大的有值元素下标
private int capacity=10;
public SimpleArrayList()
{ objArr=(T[])new Object[this.capacity];//定义一个object类型数组,并完成对T类型数组的向下类型转换,仍然会得到一个T类型的数组 objArr;
}
public SimpleArrayList(int capacity)
{
this.capacity=capacity;
objArr=(T[])new Object[this.capacity];
}
public void add(T t)
{
if (index+1>=objArr.length)
{
int oldCapacity=objArr.length;
Object oldData[]=objArr;
int newCapacity=(oldCapacity*3)/2+1;
objArr=(T[])new Object[newCapacity];
System.arraycopy(oldData, 0, objArr,0, oldCapacity);
}
objArr[index++]=t;
}
public T remove(int index)
{
if (index>this.index || index<0 || this.index<=0)
return null;
T oldValue = objArr[index];
int numMoved = objArr.length - index - 1;
if (numMoved > 0)
System.arraycopy(objArr, index+1, objArr, index, numMoved);
objArr[--this.index] = null; // Let gc do its work
return oldValue;
}
public static void main(String[] args) {
SimpleArrayList<String> sA=new SimpleArrayList<String>(6);
String sE="austin";
String sE2=sA.remove(0);
}
}

Q-4: 泛型的嵌套(nested)类定义中,成员变量也是一个泛型
总结:使用泛型,只要不在编译期出现ClassCastException,那么在运行期是不会出现ClassCastExcetion错误的.

Q-5:如何限制使用泛型中类型?即要求使用泛型是对T的类型是有要求的,而不是常用的泛型对T的类型使用可以是任何类型。
A-5:在泛型定义时使用extends关键字,让T继承某一类型或实现某一接口。从而在使用该泛型类时,对T的类型也要求必须是继承某一类或实现某一接口。
如下:public class ListGenericFoo<T extends List>{
private T[] fooArray;
public T[] getFooArray() {
return fooArray;
}
public void setFooArray(T[] fooArray) {
this.fooArray = fooArray;
}
public static void main(String[] args) {
ListGenericFoo<LinkedList> foo1=new ListGenericFoo<LinkedList>();
ListGenericFoo<ArrayList> foo2=new ListGenericFoo<ArrayList>();
LinkedList[] linkedList=new LinkedList[10];
foo1.setFooArray(linkedList);
}
}
Q-6,泛型类的通配符,如何让一个对象引用既可以引用一个泛型 A, 也可以引用别的一个泛型B
public class GenericFoo<T> {
private T foo;

public void setFoo(T foo)
{
this.foo=foo;
}
public T getFoo()
{
return this.foo;
}
}
GenericFoo<Integer> foo1=new GenericFoo<Integer>();
GenericFoo<Double> foo2=new GenericFoo<Double>();

A-6:类型的通配声明。在使用时声明,泛型类通配符
如下做法:
GenericFoo<? extends Number> ge=null;//声明一个泛型类的引用,它的含义指ge可以用来引用 List类的一个未知子类,可以是<Integer>,也可以是<Double>。
//泛型的通配符, 表示box可以作为“Number类型任一子类” 的对象引用
GenericFoo<? extends Number> box = null;
GenericFoo<Integer> intBox= new GenericFoo<Integer>();
GenericFoo<Double> dblBox= new GenericFoo<Double>();
box=intBox; //compiler OK
box.setFoo(new Integer(3));//compiler error
//最后一句将会出现编译错误,因为GenericFoo<Integer>可以看成是 GenericFoo<? extends Number>的子类,也可以看成是存放Number及其子类数据的笼子。所以box.setFoo(new Integer(3)),将不会编译通过,因为new Integer(3)是实际的数据类型,而不是一个数据笼子。
//对此还有一种解释是:如果box.setFoo(new(Integer(3))能被通过,那么你必须在box.getFoo()中进行强制类型转换,可能有如,(Integer)box.getFoo()的形式,显然这种做法违背了泛型设计的初衷,所以是不允许的。
那么这种泛型类型配符用在什么地方呢?当想把泛型类作为一个参数进行传递的时候就可以用了!(此时泛型类更象一个关Number类的笼子,所以它即是关Integer类的笼子的父类,也是关Double类的笼子的父类)
如:
public void testBox(Box<? extends Number> n){
System.out.print("invoke-cage-class,you can try pass GenericBox<Integer>");
}
应用如下:
Box<? extends Number> box=new Box<? extends Number>;
Box<Integer> intBox=new Box<Integer>;
Box<Double> douBox=new Box<Double>;
box=intBox; //compiler OK
box=douBox; //compiler OK
testBox(intBox);//compiler OK
testBox(douBox);//compiler OK

Q-7,如何继承泛型类?以及如何实现泛型类?
A-7,略

Refer url:
Subject:

Java5.0新特性之(2)For…each(简化了集合的遍历)
Description:
语法:
for(dataType element : array)
{ System.out.println(element);
}
对数组的操作:
int arr[][]={{1,2,3},{4,5,6},{7,8,9},{10,11,12} }
for( int[] row: arr)
{
for(int element:row)
{
System.out.println(element);
}
}
对泛型集合的操作:
List<String> list=new ArrayList<String>();
list.add("austin1");
list.add("austin2");
list.add("austin3");
//mehtod 1
for(int i=0;i<list.size();i++)
{
System.out.println(list.get(i));
}
//method 2
for(Iterator<String> i=list.iterator(); i.hasNext(); )
{
System.out.println(i.next());
}
//method 3
for(String element:list)
{
System.out.println(element);
}
For..Each的缺点:
对于非泛型的集合将不适合遍历每一个元素
ArrayList aList=new ArrayList();
aList.add("String");
aList.add(new Integer(3));
aList.add(new Boolean(true));
//method 2
for(Iterator<String> i=alist.iterator(); i.hasNext(); )
{
System.out.println(i.next());
}
//method 3
for(? element:list)
{
System.out.println(element);
}

Refer url:
Subject:

Java5.0新特性之(3)AutoBoxing/UnAutoBoxing
Description:
提供的功能:
简化基本数据(int, double, char, bool,float,long,byte,short)类型与它们包装类的使用。使基本数据类型自动的转入其对应的包装类叫AutoBoxing,反之叫unAutoBoxing;
注意事项:
Integer a=100;
Integer b=100;
If(a==b) //此时,因 -128<value<+127, unautoboxing成为int类型, a和b是两个int简单//类型作比较,所以是相等的.
{
System.out.println(“输出我a==b”);
}
Else
{
System.out.println(“a!=b”);
}
Integer a=200;
Integer b=200;
If(a==b) //此时,因 value不在128~+127之间, unautoboxing成为Integer对象, a和b是两个Integer对象作比较,所以是不相等的.
{
System.out.println(“a==b”);
}
Else
{
System.out.println(“输出我a!=b”);
}

Refer url:
==与equals的区别?
==对于对象永远比较的是内存地址,对原始数据类型则比较内容
Equals比较的是对象的内容
Subject:
Java5.0新特性之(4)枚举
Description:
Q-1定义枚举:
Public enum Color{
Red,
White,
Blue;
}
使用:Color mycolor=Color.Red;
A-1:枚举类型 其实与Enum/Class/interface/annotation 是在一个层次。枚举的成员其实是枚举类型的一个实例,一旦枚举类型定义,其实例个数和名字也就固定了,不允许生成新的枚举成员。所以枚举定义了,其成员也就固定了。

Q-2:枚举的用处?
Enum, class, interface, annotation
因为枚举类型的成员个数和名字是固定的,所以可以对类型变量有限制要求的场合
Q-3:枚举的比较:

Q-4:基于枚举的数据结构,枚举集合EnumSet, EnumMap
注:EnumMap中的元素的顺序是以定义Enum类型时的Enum成员变量的顺序为准的。
而HaspMap是以map.put(Element)元素的顺序为准的。
Subject:
Java5.0新特性之(5)静态导入
Description:
Q-1什么叫静态导入?
A-1:在不同的包之间,使用静态导入可以使被导入类的所有静态变量和静态方法在当前类直接可见,使用这些静态成员无须再给出他们的类名。
注:过度的使用静态导入,会降低程序的可读性。
Q-2:用法
A-2: import static com.linkedhashmap.ScoreSorter.add;

Subject:
Java5.0新特性之(6)可变参数
Description:
Q-1什么叫可变参数?
A-1: 允许方法的最后一个参数是可变的,
Q-2:定义与调用
A-1:public static int sum(String entity, int...num)
{
int sum=0;
for(int n:num)
{
System.out.print(n);
sum=sum+n;
}
return sum;

}
///
sum(“a”,1,2,3);
sum(“b”,1,2,3,4);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: