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

java语言基础入门——泛型

2016-07-31 21:35 417 查看
什么是泛型呢?泛型就是定义时(类的定义、方法的定义、形式参数的定义、成员变量的定义)不确切的指出他的类型,而是通过一个标识符表示他的类型。并且在创建的才给出它的确切类型。打个比喻,泛型就好像大学课堂用于占座的书一样,桌子上有书代表这个座位被人占用了,而具体是哪位同学占用的并不能知道,必须到上课的时候同学来了才能知道具体是哪位同学在占用。

1、泛型的声明

定义一个泛型的时候,在<>之间定义形式类型的参数,例如 class Test<T,K>;   其中K、V不代表值,而是表示类型。一般用K代表键,T代表值,E代表异常类,T代表泛型。在实例化泛型对象时,一定要在类名后面指定类型参数的具体类型,即相当于上课的时候指出具体占座同学是哪一个。例如: Test<Integer ,String> test=new Test<Integer ,String>(10,"十");

public class GenericDemo {

public static void main(String[] args) {
//泛型类型不能是int,只能是Integer等包装类
Point<Integer,String> point1=new Point<Integer,String>(8,"八");//实例化泛型类
Point<Double,Integer>point2=new Point<Double,Integer>();
//可以通过一个泛型类创建两个不同类型的对象
point2.setPx(100.3);
point2.setPy(100);
point1.setPy("十");
int px=point1.getPx();
System.out.println(px+point1.getPy());
//GenericDemo genericDemo=new GenericDemo();
tell(point2);

}
public static  void tell(Point<?,?> point) {
//通配符的使用,
//另将方法设置为静态就可以不用类的对象就可以直接调用静态方法,或者用类名调用
System.out.println(point.getPx()+"  "+point.getPy());

}

}


2、通配符: ?

通配符用在一个把含有泛型类的对象作为参数的方法中,具体情况如下:

public <?>void tell( Test<?,?> test );其中Test为含有泛型的类;

3、泛型在接口中的使用:

在类实现接口的时候可以有两种方式,可以在类实现接口的时候就明确指出泛型的具体类型,或者类实现接口的时候继续使用泛型,在实例化的时候再指出泛型的类型。

package generic;
interface Generic<T>{//定义泛型接口
public void tell();
}
class Gen1 implements Generic<String>{//一种实现泛型接口的方式
private String string;
public void tell() {
System.out.println(string);
}
public Gen1(String string) {
this.string=string;
}
}
class Gen2 <T>implements Generic<T>{//实现泛型接口的另一种方式
private T t;
public Gen2(T t) {
this.t=t;
}
@Override
public void tell() {
System.out.println(t);

}
}

public class GenericInterface {

public static void main(String[] args) {
Gen1 gen1=new Gen1("泛型接口1");
gen1.tell();
Gen2<String> gen2=new Gen2<String>("泛型接口2");
gen2.tell();

}

}


4、泛型方法:

设置一个方法,但是方法的返回值不确定,这样就要需要用泛型方法来操作

package generic;

class GenMethod{
public <T>T tell(T t) {//泛型方法
return t;
}
}
public class GenericMethod {

public static void main(String[] args) {
GenMethod genMethod=new GenMethod();
String string=genMethod.tell("泛型方法");
System.out.println(string);
}

}


5、泛型可以像其他类型一样,也能够定义他的数组类型。

package generic;

public class GenericArray {

public static void main(String[] args) {
GenericArray genericArray=new GenericArray();
Integer integerArray[]={1,2,3,4};
genericArray.tell(integerArray);

}
public <T>void tell(T t[]) {//泛型数组,<T>用于说明是泛型方法
for (int i = 0; i < t.length; i++) {
System.out.println(t[i]);
}

}

}


6、类似于public static void tell(Lest<?extends Number> list)的方法,用于说明这个方法只能被泛型为Number或Number的子类的引用调用。

相应的public static void tell(Lest<?> list)允许所有泛型的引用调用。

public static void tell(Lest<? extends Comparable> list)只允许泛型为实现了Comparable接口的实现类的引用调用。

public static void tell(Lest<?super Number> list)只允许泛型为Number以及Number父类的引用调用。

package generic;

import java.awt.List;
import java.util.ArrayList;

import org.omg.CosNaming.NamingContextExtPackage.AddressHelper;

public class GeneriCaccessAuthority {

public static void main(String[] args) {
ArrayList<String> listString=new ArrayList<String>();
listString.add("中国");
ArrayList<Integer>listInt=new ArrayList<Integer>();
listInt.add(10);
ArrayList<Number>listNumber=new ArrayList<Number>();
listNumber.add(3.4);
ArrayList<Double>listDouble=new ArrayList<Double>();
listDouble.add(5.3);
ArrayList<Object>listObject=new ArrayList<Object>();
listObject.add('a');
print(listObject);
print(listNumber);
//print(listDouble);//Double是Number的子类,没有访问print()的权限
}
public static void print(ArrayList<?super Number>arrayList){
//规定泛型只能是Number以及Number的父类的引用使用
for (Object o:arrayList) {
System.out.println(o);

}
}

}


7、使用泛型可以避免采用Object类型的引用来实现参数的“任意化”而引发的显示的“由上向下”转型时的错误,显示的由上向下转型要求程序员必须对转型类型可预知,否则将会在运行时报错。而通过泛型就可以解决这一问题,消除“由上向下”转型的隐患。

package generic;
class CPrint{
public void print(){
System.out.println("打印彩色字");
}
}
class WPrint{
public void print(){
System.out.println("打印黑白字");
}
}
class PrintHandle<T>{
private T t;
public PrintHandle(T t) {
this.t=t;
}
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}

}
public class GenericAdvantage {

public static void main(String[] args) {
PrintHandle<CPrint> cPrintHandle=new PrintHandle<CPrint>(new CPrint());
cPrintHandle.getT().print();
PrintHandle<WPrint> wPrintHandle=new PrintHandle<WPrint>(new WPrint());
wPrintHandle.getT().print();

}

}


8、另外需要注意,不能在静态方法中使用泛型,不能创建泛型类的对象,(T t=new T();),不能在catch语句中使用泛型。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: