java泛型java 自定义泛型的方法不是很懂,求大神解释下

java泛型使用和不定参数函数定义
1. 泛型使用:
&&& protected &T extends Fragment& T getFragment(Class&T& clazz, String tag){
其中有2 个地方用到泛型:
返回值为任何继承fragment的对象。
参数一为任何一个类。
2. java 函数不定参数:
&&& public void showIconsInTitleBar(View... icons) {
&&&&&&& if (icons.length == 0) {
&&&&&&&&&&&
&&&&&&& for (int i = 0; i & icons. i++) {
&&&&&&&&&&& icons[i].setVisibility(View.VISIBLE);
调用此方法可以传入任意多个view。
摘自 fhy_2008的专栏java泛型(一)、泛型的基本介绍和使用 - 无信不立 - 博客园
posts(703)
comments(13)
trackbacks(0)
现在开始深入学习java的泛型了,以前一直只是在集合中简单的使用泛型,根本就不明白泛型的原理和作用。泛型在java中,是一个十分重要的特性,所以要好好的研究下。
泛 型的定义:泛型是JDK 1.5的一项新特性,它的本质是参数化类型(Parameterized Type)的应用,也就是说所操作的数据类型被指定为一个参数,在用到的时候在指定具体的类型。这种参数类型可以用在类、接口和方法的创建中,分别称为泛 型类、泛型接口和泛型方法。
泛型思想早在C++语言的模板(Templates)中就开始生根发芽,在Java语言处于还没有出现泛型的版本时,只能通过Object是所有类型的父
类和类型强制转换两个特点的配合来实现类型泛化。例如在哈希表的存取中,JDK
1.5之前使用HashMap的get()方法,返回值就是一个Object对象,由于Java语言里面所有的类型都继承于
java.lang.Object,那Object转型为任何对象成都是有可能的。但是也因为有无限的可能性,就只有程序员和运行期的虚拟机才知道这个
Object到底是个什么类型的对象。在编译期间,编译器无法检查这个Object的强制转型是否成功,如果仅仅依赖程序员去保障这项操作的正确性,许多
ClassCastException的风险就会被转嫁到程序运行期之中。
泛型技术在C#和Java之中的使用方式看似相同,但实现上却有着根本性的分歧,C#里面泛型无论在程序源码中、编译后的IL中
(Intermediate
Language,中间语言,这时候泛型是一个占位符)或是运行期的CLR中都是切实存在的,List&int&与
List&String&就是两个不同的类型,它们在系统运行期生成,有自己的虚方法表和类型数据,这种实现称为类型膨胀,基于这种方法实现
的泛型被称为真实泛型。
& Java语言中的泛型则不一样,它只在程序源码中存在,在编译后的字节码文件中,就已经被替换为原来的原始类型(Raw
Type,也称为裸类型)了,并且在相应的地方插入了强制转型代码,因此对于运行期的Java语言来说,ArrayList&int&与
ArrayList&String&就是同一个类。所以说泛型技术实际上是Java语言的一颗语法糖,Java语言中的泛型实现方法称为类型
擦除,基于这种方法实现的泛型被称为伪泛型。(类型擦除在后面在学习)
& 使用泛型机制编写的程序代码要比那些杂乱的使用Object变量,然后再进行强制类型转换的代码具有更好的安全性和可读性。泛型对于集合类来说尤其有用。
& 泛型程序设计(Generic Programming)意味着编写的代码可以被很多不同类型的对象所重用。
实例分析:
& 在JDK1.5之前,Java泛型程序设计是用继承来实现的。因为Object类是所用类的基类,所以只需要维持一个Object类型的引用即可。就比如ArrayList只维护一个Object引用的数组:
public&class&ArrayList
&&&&public&Object&get(int&i){......}&&
&&&&public&void&add(Object&o){......}&&
&&&&......&&
&&&&private&Object[]&elementD&&
这样会有两个问题:
1、没有错误检查,可以向数组列表中添加类的对象
2、在取元素的时候,需要进行强制类型转换
这样,很容易发生错误,比如:
ArrayList&arrayList1=new&ArrayList();&&
arrayList1.add(1);&&
arrayList1.add(1L);&&
arrayList1.add("asa");&&
int&i=(Integer)&arrayList1.get(1);
这里的第一个元素是一个长整型,而你以为是整形,所以在强转的时候发生了错误。
所以。在JDK1.5之后,加入了泛型来解决类似的问题。例如在ArrayList中使用泛型:
&&&&&&&&&&&&&&&&
&&&&&&&&ArrayList&String&&arrayList2=new&ArrayList&String&();&&
&&&&&&&&arrayList2.add("asa");
&&&&&&&&String&str=arrayList2.get(0);
还要明白的是,泛型特性是向前兼容的。尽管 JDK 5.0 的标准类库中的许多类,比如集合框架,都已经泛型化了,但是使用集合类(比如
HashMap 和 ArrayList)的现有代码可以继续不加修改地在 JDK 1.5
中工作。当然,没有利用泛型的现有代码将不会赢得泛型的类型安全的好处。
在学习泛型之前,简单介绍下泛型的一些基本术语,以ArrayList&E&和
二、泛型的使用
泛型的参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口和泛型方法。下面看看具体是如何定义的。
1、泛型类的定义和使用
一个泛型类(generic class)就是具有一个或多个类型变量的类。定义一个泛型类十分简单,只需要在类名后面加上&&,再在里面加上类型参数:
class&Pair&T&&{&&
&&&&private&T&&&
&&&&&&&&public&Pair(T&value)&{&&
&&&&&&&&&&&&&&&&this.value=&&
&&&&&&&&}&&
&&&&&&&&public&T&getValue()&{&&
&&&&&&&&return&&&
&&&&public&void&setValue(T&value)&{&&
&&&&&&&&this.value&=&&&
现在我们就可以使用这个泛型类了:
public&static&void&main(String[]&args)&throws&ClassNotFoundException&{&&
&&&&&&&&Pair&String&&pair=new&Pair&String&("Hello");&&
&&&&&&&&String&str=pair.getValue();&&
&&&&&&&&System.out.println(str);&&
&&&&&&&&pair.setValue("World");&&
&&&&&&&&str=pair.getValue();&&
&&&&&&&&System.out.println(str);&&
class&Pair&T&&{&&
&&&&private&T&&&
&&&&&&&&public&Pair(T&value)&{&&
&&&&&&&&&&&&&&&&this.value=&&
&&&&&&&&}&&
&&&&&&&&public&T&getValue()&{&&
&&&&&&&&return&&&
&&&&public&void&setValue(T&value)&{&&
&&&&&&&&this.value&=&&&
现在我们就可以使用这个泛型类了:
public&static&void&main(String[]&args)&throws&ClassNotFoundException&{&&
&&&&&&&&Pair&String&&pair=new&Pair&String&("Hello");&&
&&&&&&&&String&str=pair.getValue();&&
&&&&&&&&System.out.println(str);&&
&&&&&&&&pair.setValue("World");&&
&&&&&&&&str=pair.getValue();&&
&&&&&&&&System.out.println(str);&&
Pair类引入了一个类型变量T,用尖括号&&括起来,并放在类名的后面。泛型类可以有多个类型变量。例如,可以定义Pair类,其中第一个域和第二个域使用不同的类型:
public class Pair&T,U&{......}
注意:类型变量使用大写形式,且比较短,这是很常见的。在Java库中,使用变量E表示集合的元素类型,K和V分别表示关键字与值的类型。(需要时还可以用临近的字母U和S)表示&任意类型&。
2、泛型接口的定义和使用
定义泛型接口和泛型类差不多,看下面简单的例子:
interface&Show&T,U&{&&
&&&&void&show(T&t,U&u);&&
class&ShowTest&implements&Show&String,Date&{&&
&&&&@Override&&
&&&&public&void&show(String&str,Date&date)&{&&
&&&&&&&&System.out.println(str);&&
&&&&&&&&System.out.println(date);&&
测试一下:
public&static&void&main(String[]&args)&throws&ClassNotFoundException&{&&
&&&&&&&&ShowTest&showTest=new&ShowTest();&&
&&&&&&&&showTest.show("Hello",new&Date());&&
3、泛型方法的定义和使用
泛型类在多个方法签名间实施类型约束。在 List&V& 中,类型参数 V 出现在 get()、add()、contains()
等方法的签名中。当创建一个 Map&K, V& 类型的变量时,您就在方法之间宣称一个类型约束。您传递给 add() 的值将与
get() 返回的值的类型相同。
类似地,之所以声明泛型方法,一般是因为您想要在该方法的多个参数之间宣称一个类型约束。
举个简单的例子:
public&static&void&main(String[]&args)&throws&ClassNotFoundException&{&&
&&&&&&&&String&str=get("Hello",&"World");&&
&&&&&&&&System.out.println(str);&&
&&&&public&static&&T,&U&&T&get(T&t,&U&u)&{&&
&&&&&&&&if&(u&!=&null)&&
&&&&&&&&&&&&return&t;&&
&&&&&&&&else&&
&&&&&&&&&&&&return&&&
三、泛型变量的类型限定
在上面,我们简单的学习了泛型类、泛型接口和泛型方法。我们都是直接使用&T&这样的形式来完成泛型类型的声明。
有的时候,类、接口或方法需要对类型变量加以约束。看下面的例子:
有这样一个简单的泛型方法:
public&static&&T&&T&get(T&t1,T&t2)&{&&
&&&&&&&&if(t1.compareTo(t2)&=0);
&&&&&&&&return&t1;&&
因为,在编译之前,也就是我们还在定义这个泛型方法的时候,我们并不知道这个泛型类型T,到底是什么类型,所以,只能默认T为原始类型Object。所以它只能调用来自于Object的那几个方法,而不能调用compareTo方法。
可我的本意就是要比较t1和t2,怎么办呢?这个时候,就要使用类型限定,对类型变量T设置限定(bound)来做到这一点。
我们知道,所有实现Comparable接口的方法,都会有compareTo方法。所以,可以对&T&做如下限定:
public&static&&T&extends&Comparable&&T&get(T&t1,T&t2)&{&
&&&&&&&&if(t1.compareTo(t2)&=0);&&
&&&&&&&&return&t1;&&
类型限定在泛型类、泛型接口和泛型方法中都可以使用,不过要注意下面几点:
1、不管该限定是类还是接口,统一都使用关键字 extends
2、可以使用&符号给出多个限定,比如
public&static&&T&extends&Comparable&Serializable&&T&get(T&t1,T&t2)&&
3、如果限定既有接口也有类,那么类必须只有一个,并且放在首位置
public&static&&T&extends&Object&Comparable&Serializable&&T&get(T&t1,T&t2)&java泛型_百度百科
清除历史记录关闭
声明:百科词条人人可编辑,词条创建和修改均免费,绝不存在官方及代理商付费代编,请勿上当受骗。
泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为、泛型接口、泛型方法。 引入泛型的好处是安全简单。在Java SE 1.5之前,没有泛型的的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的,而这种转换是要求开发者对类型可以预知的情况下进行的。对于强制类型转换错误的情况,可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。泛型的好处是在编译的时候检查,并且所有的都是自动和的,以提高代码的重用率。
java泛型规则限制
1、泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。
2、同一种泛型可以对应多个版本(因为参数类型是不确定的),不同版本的实例是不兼容的。
3、泛型的类型参数可以有多个。
4、泛型的参数类型可以使用extends语句,例如&T extends superclass&。习惯上称为“有界类型”。
5、泛型的参数类型还可以是类型。例如Class&?& classType = Class.forName(&java.lang.String&);
泛型还有接口、方法等等,内容很多,需要花费一番功夫才能理解掌握并熟练应用。在此给出我曾经了解泛型时候写出的两个例子(根据看的印象写的),实现同样的功能,一个使用了泛型,一个没有使用,通过对比,可以很快学会泛型的应用,学会这个基本上学会了泛型70%的内容。
例子一:使用了泛型
class&Gen&T&&{
&&&&private&T&&//&定义泛型成员变量
&&&&public&Gen(T&ob)&{
&&&&&&&&this.ob&=&
&&&&public&T&getOb()&{
&&&&&&&&return&
&&&&public&void&setOb(T&ob)&{
&&&&&&&&this.ob&=&
&&&&public&void&showType()&{
&&&&&&&&System.out.println(&T的实际类型是:&&&+&ob.getClass().getName());
public&class&GenDemo&{
&&&&public&static&void&main(String[]&args)&{
&&&&&&&&//&定义泛型类Gen的一个Integer版本
&&&&&&&&Gen&Integer&&intOb&=&new&Gen&Integer&(88);
&&&&&&&&intOb.showType();
&&&&&&&&int&i&=&intOb.getOb();
&&&&&&&&System.out.println(&value=&&&+&i);
&&&&&&&&System.out.println(&----------------------------------&);
&&&&&&&&//&定义泛型类Gen的一个String版本
&&&&&&&&Gen&String&&strOb&=&new&Gen&String&(&Hello&Gen!&);
&&&&&&&&strOb.showType();
&&&&&&&&String&s&=&strOb.getOb();
&&&&&&&&System.out.println(&value=&&&+&s);
例子二:没有使用泛型
class&Gen2&{
&&&&private&Object&&//&定义一个通用类型成员
&&&&public&Gen2(Object&ob)&{
&&&&&&&&this.ob&=&
&&&&public&Object&getOb()&{
&&&&&&&&return&
&&&&public&void&setOb(Object&ob)&{
&&&&&&&&this.ob&=&
&&&&public&void&showTyep()&{
&&&&&&&&System.out.println(&T的实际类型是:&&&+&ob.getClass().getName());
public&class&GenDemo2&{
&&&&public&static&void&main(String[]&args)&{
&&&&&&&&//&定义类Gen2的一个Integer版本
&&&&&&&&Gen2&intOb&=&new&Gen2(new&Integer(88));
&&&&&&&&intOb.showTyep();
&&&&&&&&int&i&=&(Integer)&intOb.getOb();
&&&&&&&&System.out.println(&value=&&&+&i);
&&&&&&&&System.out.println(&---------------------------------&);
&&&&&&&&//&定义类Gen2的一个String版本
&&&&&&&&Gen2&strOb&=&new&Gen2(&Hello&Gen!&);
&&&&&&&&strOb.showTyep();
&&&&&&&&String&s&=&(String)&strOb.getOb();
&&&&&&&&System.out.println(&value=&&&+&s);
运行结果:
两个例子运行Demo结果是相同的,控制台输出结果如下:
T的实际类型是:java.lang.Integer
----------------------------------
T的实际类型是: java.lang.String
value= Hello Gen!
Process finished with exit code 0
看明白这个,以后基本的泛型应用和代码阅读就不成问题了。
java泛型深入泛型
java泛型原始代码
有两个类如下,要构造两个类的对象,并打印出各自的成员x。
public&class&StringFoo&{
&&&&private&String&x;
&&&&public&StringFoo(String&x)&{
&&&&&&&&this.x&=&x;
&&&&public&String&getX()&{
&&&&&&&&return&x;
&&&&public&void&setX(String&x)&{
&&&&&&&&this.x&=&x;
public&class&DoubleFoo&{
&&&&private&Double&x;
&&&&public&DoubleFoo(Double&x)&{
&&&&&&&&this.x&=&x;
&&&&public&Double&getX()&{
&&&&&&&&return&x;
&&&&public&void&setX(Double&x)&{
&&&&&&&&this.x&=&x;
java泛型重构
因为上面的类中,成员和方法的逻辑都一样,就是类型不一样,因此考虑重构。Object是所有类的父类,因此可以考虑用Object做为成员类型,这样就可以实现通用了,实际上就是“Object泛型”,暂时这么称呼。
public&class&ObjectFoo&{
&&&&private&Object&x;
&&&&public&ObjectFoo(Object&x)&{
&&&&&&&&this.x&=&x;
&&&&public&Object&getX()&{
&&&&&&&&return&x;
&&&&public&void&setX(Object&x)&{
&&&&&&&&this.x&=&x;
写出Demo方法如下:
public&class&ObjectFooDemo&{
&&&&public&static&void&main(String&args[])&{
&&&&&&&&ObjectFoo&strFoo&=&new&ObjectFoo(new&String(&Hello&Generics!&));
&&&&&&&&ObjectFoo&douFoo&=&new&ObjectFoo(new&Double(new&Double(&33&)));
&&&&&&&&ObjectFoo&objFoo&=&new&ObjectFoo(new&Object());
&&&&&&&&System.out.println(&strFoo.getX=&&+&(String)&strFoo.getX());
&&&&&&&&System.out.println(&douFoo.getX=&&+&(Double)&douFoo.getX());
&&&&&&&&System.out.println(&objFoo.getX=&&+&objFoo.getX());
运行结果如下:
strFoo.getX=Hello Generics!
douFoo.getX=33.0
objFoo.getX=java.lang.Object@15db9742
解说:在Java 5之前,为了让类有通用性,往往将参数类型、返回类型设置为Object类型,当获取这些返回类型来使用时候,必须将其“强制”转换为原有的类型或者接口,然后才可以调用对象上的方法。
java泛型实现
很麻烦,我还要事先知道各个Object具体类型是什么,才能做出正确转换。否则,要是转换的类型不对,比如将“Hello Generics!”字符串为Double,那么编译的时候不会报错,可是运行的时候就挂了。那有没有不强制转换的办法----有,改用 Java5泛型来实现。
class&GenericsFoo&T&&{
&&&&private&T&x;
&&&&public&GenericsFoo(T&x)&{
&&&&&&&&this.x&=&x;
&&&&public&T&getX()&{
&&&&&&&&return&x;
&&&&public&void&setX(T&x)&{
&&&&&&&&this.x&=&x;
public&class&GenericsFooDemo&{
&&&&public&static&void&main(String&args[])&{
&&&&&&&&GenericsFoo&String&&strFoo&=&new&GenericsFoo&String&(&Hello&Generics!&);
&&&&&&&&GenericsFoo&Double&&douFoo&=&new&GenericsFoo&Double&(new&Double(&33&));
&&&&&&&&GenericsFoo&Object&&objFoo&=&new&GenericsFoo&Object&(new&Object());
&&&&&&&&System.out.println(&strFoo.getX=&&+&strFoo.getX());
&&&&&&&&System.out.println(&douFoo.getX=&&+&douFoo.getX());
&&&&&&&&System.out.println(&objFoo.getX=&&+&objFoo.getX());
运行结果:
strFoo.getX=Hello Generics!
douFoo.getX=33.0
objFoo.getX=java.lang.Object@15db9742
和使用“Object泛型”方式实现结果的完全一样,但是这个Demo简单多了,里面没有信息。
下面解释一下上面的语法:
使用&T&来声明一个类型持有者名称,然后就可以把T当作一个类型代表来声明成员、参数和返回值类型。
当然T仅仅是个名字,这个名字可以自行定义。
class GenericsFoo&T& 声明了一个泛型类,这个T没有任何限制,实际上相当于Object类型,实际上相当于 class GenericsFoo&T extends Object&。
与Object泛型类相比,使用泛型所定义的类在声明和构造实例的时候,可以使用“&实际类型&”来一并指定泛型类型持有者的真实类型。类如
GenericsFoo&Double& douFoo=new GenericsFoo&Double&(new Double(&33&));
当然,也可以在构造对象的时候不使用尖括号指定型的真实类型,但是你在使用该对象的时候,就需要了。比如:GenericsFoo douFoo=new GenericsFoo(new Double(&33&));
实际上,当构造对象时不指定类型信息的时候,默认会使用Object类型,这也是要强制转换的原因。
java泛型高级应用
java泛型限制泛型
在上面的例子中,由于没有限制class GenericsFoo&T&类型持有者T的范围,实际上这里的限定类型相当于Object,这和“Object泛型”实质是一样的。限制比如我们要限制T为集合接口类型。只需要这么做:
class GenericsFoo&T extends Collection&,这样类中的泛型T只能是的实现类,传入非Collection接口编译会出错。
注意:&T extends Collection&这里的限定使用extends,后面可以是类也可以是接口。但这里的extends已经不是继承的含义了,应该理解为T类型是实现Collection接口的类型,或者T是继承了XX类的类型。
下面继续对上面的例子改进,我只要实现了集合接口的类型:
public&class&CollectionGenFoo&T&extends&Collection&&{
&&&&private&T&x;
&&&&public&CollectionGenFoo(T&x)&{
&&&&&&&&this.x&=&x;
&&&&public&T&getX()&{
&&&&&&&&return&x;
&&&&public&void&setX(T&x)&{
&&&&&&&&this.x&=&x;
实例化的时候可以这么写:
public&class&CollectionGenFooDemo&{
&&&&public&static&void&main(String&args[])&{
&&&&&&&&CollectionGenFoo&ArrayList&&listFoo&=&
&&&&&&&&listFoo&=&new&CollectionGenFoo&ArrayList&(new&ArrayList());
&&&&&&&&//&出错了,不让这么干。
&&&&&&&&//&原来作者写的这个地方有误,需要将listFoo改为listFoo1
&&&&&&&&//&需要将CollectionGenFoo&Collection&改为CollectionGenFoo&ArrayList&
&&&&&&&&//&CollectionGenFoo&Collection&&listFoo1&=&
&&&&&&&&//&listFoo1=new&CollectionGenFoo&ArrayList&(new&ArrayList());
&&&&&&&&System.out.println(&实例化成功!&);
当前看到的这个写法是可以编译通过,并运行成功。可是注释掉的两行加上就出错了,因为&T extends Collection&这么定义类型的时候,就限定了构造此类实例的时候T是确定的一个类型,这个类型实现了Collection接口,但是实现 Collection接口的类很多很多,如果针对每一种都要写出具体的子类类型,那也太麻烦了,我干脆还不如用Object通用一下。别急,泛型针对这种情况还有更好的解决方案,那就是“泛型”。
java泛型多接口限制
虽然Java泛型简单的用 extends 统一的表示了原有的 extends 和 implements 的概念,但仍要遵循应用的体系,Java 只能继承一个类,但可以实现多个接口,所以你的某个类型需要用 extends 限定,且有多种类型的时候,只能存在一个是类,并且类写在第一位,接口列在后面,也就是:
&T extends SomeClass & interface1 & interface2 & interface3&
这里的例子仅演示了泛型方法的类型限定,对于泛型类中类型参数的限制用完全一样的规则,只是加在类声明的头部,如:
public&class&Demo&T&extends&Comparable&&&Serializable&&{
&&&&//&T类型就可以用Comparable声明的方法和Seriablizable所拥有的特性了
java泛型通配符泛型
为了解决类型被限制死了不能动态根据实例来确定的缺点,引入了“通配符泛型”,针对上面的例子,使用通配泛型格式为&? extends Collection&,“?”代表未知类型,这个类型是实现Collection接口。那么上面实现的方式可以写为:
public&class&CollectionGenFooDemo&{
&&&&public&static&void&main(String&args[])&{
&&&&&&&&//CollectionGenFoo&ArrayList&&listFoo&=&
&&&&&&&&//listFoo&=&new&CollectionGenFoo&ArrayList&(new&ArrayList());
&&&CollectionGenFoo&?&&listFoo1&=&
&&&&&&&&listFoo1=new&CollectionGenFoo&ArrayList&(new&ArrayList());
&&&&&&&&System.out.println(&实例化成功!&);
1、如果只指定了&?&,而没有extends,则默认是允许Object及其下的任何Java类了。也就是任意类。
2、泛型不单可以向上限制,如&? extends Collection&,还可以向下限制,如&? super Double&,表示类型只能接受Double及其上层父类类型,如Number、Object类型的实例。
3、定义可以有多个泛型参数,中间用逗号隔开,还可以定义泛型接口,泛型方法。这些都与泛型类中泛型的使用规则类似。
java泛型泛型方法
是否拥有泛型方法,与其所在的类是否泛型没有关系。要定义泛型方法,只需将泛型参数列表置于返回值前。如:
public&class&ExampleA&{
&&&&public&&T&&void&f(T&x)&{
&&&&&&&&System.out.println(x.getClass().getName());
&&&&public&static&void&main(String[]&args)&{
&&&&&&&&ExampleA&ea&=&new&ExampleA();
&&&&&&&&ea.f(&&&);
&&&&&&&&ea.f(10);
&&&&&&&&ea.f('a');
&&&&&&&&ea.f(ea);
输出结果:
java.lang.String
java.lang.Integer
java.lang.Character
使用泛型方法时,不必指明参数类型,会自己找出具体的类型。泛型方法除了定义不同,调用就像普通方法一样。
需要注意,一个static方法,无法访问的类型参数,所以,若要static方法需要使用泛型能力,必须使其成为泛型方法。
java泛型关于Java
詹姆斯·戈士林博士以“Java技术之父”闻名于世。他是Java技术的创始人, 作为Sun研究院院士,他亲手设计了Java语言,完成了Java技术的原始编译器和虚拟机。在他的带领下,Java现已成为互联网的标准编程模式以及分布式企业级应用的事实标准,其跨平台的技术优势为网络计算带来了划时代的变革。戈士林博士积极致力于软件开发工具的研究,以使软件开发工具的功能更强大,更容易为开发人员所使用,确保应用、服务开发的迅速完成。
Java技术是Sun公司在1995年5月正式推出的。十年多来,Java已从编程语言发展成为全球第一大通用开发平台。Java技术已为计算机行业主要公司所采纳,同时也被越来越多的国际技术标准化组织所接受。1999年,Sun推出了以Java 2平台为核心的J2EE、J2SE和J2ME三大平台。随着三大平台的迅速推进,在世界上形成了一股巨大的Java应用浪潮。同时,Java技术还引发了一场无法停止的大变革,为整个Java社团带来了巨大的潮水般的商业机会。
.新华[引用日期]
清除历史记录关闭java 泛型&T& 和 &?&的区别?网上答案看不懂,屌大的通俗的解释一下呗
<a data-traceid="question_detail_above_text_l&&
java 泛型&T& 和 &?&的区别?网上答案看不懂,屌大的通俗的解释一下呗
1. & &'?' 是通配符。它指的是 一个接口类型 的任何一个子类 类型,当然,也包括这个接口本身的类型。因为‘?’是通配符,因此在类的声明和方法的声明中用到的 ‘?’,是没有关联的。 所以,只要:List&?& &getONEITEM(); 就可以通过编译。&
例如,下列场景允许 List的元素可以是 Bar 的任何一个子类的类型:&
interface Foo {
List&? extends Bar& get();
2. &&'T' 是指在某一给定场合下一个接口的特定实现, 只能代表一个类型。
例如,下列场景意味着,整个接口(类) 仅能处理 Bar 这一个类型的对象:
interface Foo&T extends Bar& {
List&T& get();
的最佳答案(获 17 个点赞)。若有意思没有转达(翻译)正确的地方,请各位指正。
--- 共有 2 条评论 ---
好像又懂了 T表示只能一种实现Bar的类型 ?可以是多种实现Bar的类型
关于T还是没看懂
我屌大,给你顶一下!
本质上一样的,但是在使用的时候。比如:写了一个Demo&T& 类。在方法里面我们可以直接使用T。但是?不行。T.class你能写个?.class吗?。
个人理解,轻喷
泛型&&中代表的只是一个引用符号,和你定义一个变量名没啥区别,在设计语法上符合java变量命名规则即可,&A1&&BB_BB&&C123&&D56&都可以,但是?不符合命名规则,在定义时不能用。?一般只出现在文档API中可以认为是伪代码,通常表示不确定的类型。
?&#20195;&#34920;&&#20219;&#20309;&&#65292;T&#20195;&#34920;&#30340;&#23601;&#26159;T&#12290;&#19968;&#20010;&#26080;&#38480;&#23450;&#65292;&#19968;&#20010;&#26377;&#38480;&#23450;&#12290;&#21306;&#21035;&#22312;&#20110;&#65292;&#22312;&#20219;&#20309;&#22320;&#26041;&#65292;?&#37117;&#26159;&#29420;&#31435;&#30340;&#65292;&#32780;T, &#22810;&#22788;&#29992;&#21516;&#19968;&#20010;T&#37027;&#20040;&#23601;&#26159;&#19968;&#33268;&#30340;&#65292;&#38480;&#23450;&#30340;&#65292;&#20320;&#19981;&#33021;&#25913;&#25104;E, &#22312;&#23454;&#21442;&#20320;&#19981;&#33021;&#19968;&#20010;&#22320;&#26041;&#29992;Integer, &#19968;&#20010;&#22320;&#26041;&#29992;String&#12290;&#32780;?&#21017;&#26080;&#38480;&#21046;&#12290;
所谓,就是在定义类、接口、方法、参数或成员变量的时候,指定它们操作对象的类型为通用类型。
使用 尖括号 && 操作符 (The diamond operator )表示泛型, 尖括号内可以放置大写字母 (代表一个未知类型) 或问号 ? (代表若干个类型)作为参数。比如,习惯上选择以下字母代表某种类型:
T&意味某种类型 &
E 意味 链表、数组里的元素,如List&E& list 表示 list 里的元素。
K意味map(k,v) 里的键值 Key
V 意味 返回或映射的值。
然而,泛型的运用要受到如下限制 :
不能使用基本类型的类型参数,可以使用其包装类型代替。
不能实例化泛型对象或数组,如:
&&&&&&&& T t = new T();& T[] a=new T[5];
& & &5,. 不能使用泛型数组,如:
import java.util.*;
public class Test{
public static void main(String args[]){
List&String& arr[] = new ArrayList&String&[5];
D:\java\test\OS_China\generic&javac Test.java
Test.java:5: 错误: 创建泛型数组
List&String& arr[] = new ArrayList&String&[5];
至于代表若干类的,放在尖括号内的:&?&,还分 上限通配符 () 和 下限通配符 ()。
上限通配符 &? &extends &U& 可以代表这个未知类型 U,或者 通过关键字 extends 所能想象出的 U 类的任何一个子类。同样,下限通配符 &? &super &L& 可以代表这个未知类型 L,或者 通过关键字 super 所能想象出的 L类的任何一个超类。
这里分别以多个接口 interface 和 多个类 class 为基础, 创建 继承关系。
并以通过编译的代码, 证明以上论点成立。
/* &? super T& 与 &? extends T& 的区别,
T 代表一个给定的接口
import java.util.*;
interface A1{}
interface A2{}
interface A3{}
interface A4{}
interface B1 extends A1{}
interface B2 extends A1,A2{}
interface B3 extends A3,A4{}
interface B4 extends A4{}
interface C1 extends B2{}
interface C2 extends B2,B3{}
interface C3 extends B3{}
interface D1 extends C1,C2{}
interface D2 extends C2{}
interface E1 extends D1{}
interface E2 extends D1{}
interface E3 extends D2{}
interface E4 extends D2{}
public class UP_Interface {
public static void main(String args[]){
/********************************************
* 此处 extends 表示 有上界的统配符 ?,上界为
* 由此定义的引用 listUpper可以作为
* 接下来的 7 种 子泛型类型的 ArrayList 的引用来使用。
**********************************************/
List&? extends C2& listU//上界统配符 ?, 上界为
listUpper=new ArrayList&C2&();//能存储 C2 D1 D2 E1 E2 E3 E4
listUpper=new ArrayList&D1&();//能存储
listUpper=new ArrayList&D2&();//能存储
listUpper=new ArrayList&E1&();//能存储
listUpper=new ArrayList&E2&();//能存储
listUpper=new ArrayList&E3&();//能存储
listUpper=new ArrayList&E4&();//能存储
/*************************************************
* super 表示有下界的统配符 ? ,下界为
* 由此定义的引用 listLower 可以作为
* 接下来的 7 种 子泛型类型的 ArrayList 的引用来使用。
***************************************************/
List&? super C2& listL
listLower=new ArrayList&A1&(); //能存储 A1
D1 D2 E1 E2 E3 E4
listLower=new ArrayList&A2&(); //能存储
D1 D2 E1 E2 E3 E4
listLower=new ArrayList&A3&(); //能存储
C2 C3 D1 D2 E1 E2 E3 E4
listLower=new ArrayList&A4&(); //能存储
C2 C3 D1 D2 E1 E2 E3 E4
listLower=new ArrayList&B2&(); //能存储
D1 D2 E1 E2 E3 E4
listLower=new ArrayList&B3&(); //能存储
C2 C3 D1 D2 E1 E2 E3 E4
listLower=new ArrayList&C2&();// 能存储
D1 D2 E1 E2 E3 E4
/* &? super T& 与 &? extends T& 的区别,
T 代表一个给定的类
import java.util.*;
class A1{}
class A2{}
class A3{}
class A4{}
class B1 extends A1{}
class B2 extends A1{}
class B3 extends A3{}
class B4 extends A4{}
class C1 extends B2{}
class C2 extends B2{}
class C3 extends B3{}
class D1 extends C1{}
class D2 extends C2{}
class E1 extends D1{}
class E2 extends D1{}
class E3 extends D2{}
class E4 extends D2{}
public class UP_Class{
public static void main(String args[]){
/********************************************
* 此处 extends 表示 有上界的统配符 ?,上界为
* 由此定义的引用 listUpper可以作为
* 接下来的 7 种 子泛型类型的 ArrayList 的引用来使用。
**********************************************/
List&? extends C2& listU//统配符 ? 的上界为
listUpper=new ArrayList&C2&();//能存储 C2 D2 E3 E4
listUpper=new ArrayList&D2&();//能存储 D2 E3 E4
listUpper=new ArrayList&E3&();
listUpper=new ArrayList&E4&();
/*************************************************
* super 表示有下界的统配符 ? ,下界为
* 由此定义的引用 listLower 可以作为
* 接下来的 7 种 子泛型类型的 ArrayList 的引用来使用。
***************************************************/
List&? super C2& listL
listLower=new ArrayList&A1&(); //能存储 A1 B1 B2 C1 C2
D1 D2 E1 E2 E3 E4
listLower=new ArrayList&B2&(); //能存储 B2
D1 D2 E1 E2 E3 E4
listLower=new ArrayList&C2&();// 能存储 D2 E3 E4
&#25628;&#27867;&#22411; &#21327;&#21464;
&#26368;&#22823;&#38382;&#39064;&#65292;&#29992;&#65311;&#22768;&#26126;&#30340;&#33539;&#22411;&#23545;&#20110;&#32534;&#35793;&#22120;&#30340;&#24378;&#36716;&#25805;&#20316;&#34987;&#19981;&#20855;&#22791;&#65292;&#32780;&#29992;T&#22768;&#26126;&#30340;&#20854;&#19978;&#23618;&#27966;&#29983;&#20381;&#28982;&#26159;OBject&#31867;&#22411;
T&#26159;&#27867;&#22411;&#31867;&#22411;&#21442;&#25968;&#65292;&#29992;&#20110;&#23450;&#20041;&#27867;&#22411;&#65292;&#26412;&#36523;&#19981;&#20195;&#34920;&#20855;&#20307;&#31867;&#22411;&#65292;&#20855;&#20307;&#31867;&#22411;&#26377;&#20351;&#29992;&#27867;&#22411;&#26102;&#20915;&#23450;&#65292;&#31867;&#27604;&#23450;&#20041;&#20989;&#25968;&#26102;&#30340;&#24418;&#21442;&#65292;&#27809;&#26377;&#20540;&#65292;&#20540;&#30001;&#35843;&#29992;&#20989;&#25968;&#26102;&#30340;&#23454;&#21442;&#20915;&#23450;&#12290;
&#32780;?&#26159;&#29992;&#26469;&#22788;&#29702;&#21327;&#21464;&#36870;&#21464;&#30340;&#65292;&#20855;&#20307;&#35831;&#30475;&#19979;&#38754;&#30340;&#25991;&#31456;&#12290;
&#26377;&#20851;&#20110; &?& &#19982; &? extends Object&&#26159;&#21542;&#26159;&#19968;&#22238;&#20107;
&#20170;&#22825;&#20013;&#21320;&#21457;&#29616;&#21516;&#20107;&#26700;&#19978;&#26377;&#26412;&#12298;Java&#32534;&#31243;&#24605;&#24819;&#12299;&#31532;&#22235;&#29256;&#65292;&#38543;&#25163;&#32763;&#20102;&#19968;&#19979;&#65292;&#21457;&#29616;&#27867;&#22411;&#19968;&#31456;&#30340;&#20171;&#32461;&#20013;&#65292;&#26377;&#21477;&#25551;&#36848;&#65306;&UnboundedWildcards.java &#23637;&#31034;&#20102;&#32534;&#35793;&#22120;&#22788;&#29702;List&?&&#21644;List&? Extends Object&&#26102;&#26159;&#19981;&#21516;&#30340;&#12290;&
http://hongjiang.info/java-generics/}

我要回帖

更多关于 java 定义list泛型 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信