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,"十");
2、通配符: ?
通配符用在一个把含有泛型类的对象作为参数的方法中,具体情况如下:
public <?>void tell( Test<?,?> test );其中Test为含有泛型的类;
3、泛型在接口中的使用:
在类实现接口的时候可以有两种方式,可以在类实现接口的时候就明确指出泛型的具体类型,或者类实现接口的时候继续使用泛型,在实例化的时候再指出泛型的类型。
4、泛型方法:
设置一个方法,但是方法的返回值不确定,这样就要需要用泛型方法来操作
5、泛型可以像其他类型一样,也能够定义他的数组类型。
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父类的引用调用。
7、使用泛型可以避免采用Object类型的引用来实现参数的“任意化”而引发的显示的“由上向下”转型时的错误,显示的由上向下转型要求程序员必须对转型类型可预知,否则将会在运行时报错。而通过泛型就可以解决这一问题,消除“由上向下”转型的隐患。
8、另外需要注意,不能在静态方法中使用泛型,不能创建泛型类的对象,(T t=new T();),不能在catch语句中使用泛型。
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语句中使用泛型。
相关文章推荐
- Java基础:Java泛型编程快速入门
- java-基础入门-泛型数组列表-解决运行时动态更改数组的问题
- java基础入门-泛型(1)-为什么需要使用泛型?
- [Java入门笔记] Java语言基础(一):注释、标识符与关键字
- [Java入门笔记] Java语言基础(四):流程控制
- JAVA基础:Java泛型编程快速入门
- java基础入门-泛型(1)-为什么需要使用泛型?
- Java语言基础——06.集合框架(2)泛型和Map集合
- 黑马程序员—Java入门及Java语言基础组成
- [Java入门笔记] Java语言基础(二):常量、变量与数据类型
- 黑马程序员——Java语言基础——06.集合框架(2)泛型和Map集合
- Java语言基础-常用对象API(二)泛型、Map集合
- 黑马程序员-Java语言基础– 泛型 第15天
- 【Java 基础】Java 泛型简单入门
- java-基础入门-泛型数组列表-解决运行时动态更改数组的问题
- Java基础:Java泛型编程快速入门
- java语言基础入门之猜拳游戏(知识点回顾)
- 【百度文库课程】Java语言基础与OOP入门学习笔记一
- [Java入门笔记] Java语言基础(三):运算符
- [Java入门笔记] Java语言基础(五):数组