java java 接口继承泛型接口

interface Info&T&{ 2
public T getVar(); 3 } 4
class Infolmpl implements info&String&{ 5
private S 6
public Infolmpl(String Var){ 7
this.setVar(var); 8
public void setVar(String var){10
this.var=11
public String getVar(){13
return this.14
}16 17 public class dsadas {18
public static void main(String args[]){19
Info&String& i=null;20
i=new Infolmpl("lixinghua");21
System.out.println("content:"+i.getVar());22
在接口中指定类型。。。
阅读(...) 评论()答复: Java获得泛型类型 - Script Ahead, Code Behind - ITeye博客
博客分类:
转自的回复,内容有细微调整。
Java泛型有这么一种规律:
位于声明一侧的,源码里写了什么到运行时就能看到什么;
位于使用一侧的,源码里写什么到运行时都没了。
什么意思呢?“声明一侧”包括泛型类型(泛型类与泛型接口)声明、带有泛型参数的方法和域的声明。注意局部变量的声明不算在内,那个属于“使用”一侧。
import java.util.L
import java.util.M
public class GenericClass&T& {
private List&T&
private Map&String, T&
public &U& U genericMethod(Map&T, U& m) { // 4
}
上面代码里,带有注释的行里的泛型信息在运行时都还能获取到,原则是源码里写了什么运行时就能得到什么。针对1的GenericClass&T&,运行时通过Class.getTypeParameters()方法得到的数组可以获取那个“T”;同理,2的T、3的java.lang.String与T、4的T与U都可以获得。源码文本里写的是什么运行时就能得到什么;像是T、U等在运行时的实际类型是获取不到的。
这是因为从Java 5开始class文件的格式有了调整,规定这些泛型信息要写到class文件中。以上面的map为例,通过javap来看它的元数据可以看到记录了这样的信息:
private java.util.M
Signature: Ljava/util/M
Signature: length = 0x2
00 0A
乍一看,private java.util.M不正好显示了它的泛型类型被擦除了么?
但仔细看会发现有两个Signature,下面的一个有两字节的数据,0x0A。到常量池找到0x0A对应的项,是:
const #10 = Asciz
Ljava/util/Map&Ljava/lang/STT;&;;
也就是内容为“Ljava/util/Map&Ljava/lang/STT;&;”的一个字符串。
根据Java 5开始的新class文件格式规范,方法与域的描述符增添了对泛型信息的记录,用一对尖括号包围泛型参数,其中普通的引用类型用“La/b/c/D;”的格式记录,未绑定值的泛型变量用“T”的格式记录,其中xxx就是源码中声明的泛型变量名。类型声明的泛型信息也以类似下面的方式记了下来:
public class GenericClass extends java.lang.Object
Signature: length = 0x2
const #18 = Asciz
&T:Ljava/lang/O&Ljava/lang/O;
详细信息请参考官方文档:
该文档也将会被整合到JVM规范第三版中。可惜第三版现在只有草案,最终版本什么时候发布还遥遥无期。
相比之下,“使用一侧”的泛型信息则完全没有被保留下来,在Java源码编译到class文件后就确实丢失了。也就是说,在方法体内的泛型局部变量、泛型方法调用之类的泛型信息编译后都消失了。
import java.util.ArrayL
import java.util.L
public class TestClass {
public static void main(String[] args) {
List&String& list =
list = new ArrayList&String&(); // 2
for (int i = 0; i & 10; i++) ;
}
上面代码中,1留下的痕迹是:main()方法的StackMapTable属性里可以看到:
StackMapTable: number_of_entries = 2
frame_type = 253 /* append */
offset_delta = 12
locals = [ class java/util/List, int ]
frame_type = 250 /* chop */
offset_delta = 11
但这里是没有留下泛型信息的。这段代码只所以写了个空的for循环就是为了迫使javac生成那个StackMapTable,让1多留个影。当整个方法只有一个基本块的时候javac就不会生成StackMapTable属性,就看不到这可爱的数据结构了。
如果main()里用到了list的方法,那么那些方法调用点上也会留下1的痕迹,例如如果调用list.add("");,则会留下“java/util/List.add:(Ljava/lang/O)Z”这种记录。
2留下的是“java/util/ArrayList."&init&":()V”,同样也丢失了泛型信息。
由上述讨论可知,想对带有未绑定的泛型变量的泛型类型获取其实际类型是不现实的,因为class文件里根本没记录实际类型的信息。觉得这句话太拗口的话用例子来理解:要想对java.util.List&E&获取E的实际类型是不现实的,因为List.class文件里只记录了E,却没记录使用List&E&时E的实际类型。
想对局部变量等“使用一侧”的已绑定的泛型类型获取其实际类型也不现实,同样是因为class文件中根本没记录这个信息。例子直接看上面讲“使用一侧”的就可以了。
知道了什么信息有记录,什么信息没有记录之后,也就可以省点力气不去纠结“拿不到T的实际类型”、“建不出T类型的数组”、“不能对T类型做instanceof”之类的问题了orz
sohuexe 写道也不是完全没有办法,最典型的就是《java Persistence with hibernate》 的例子可以参照。那种情况在文章中描述的情况以及包括了,正好说明了class文件记录了什么而又没有记录什么——一个非泛型的派生类继承一个泛型基类时,派生类的class文件对基类的记录就包含了已经确定了值了泛型参数,相对泛型基类来说,这里仍然是“声明”一侧,于是源码中泛型信息在文本怎么写的就在class文件里记录了什么。是的,没有意思,关键是要运行时,非申明式的定义。获得参数类型是徒劳的,一般我会HardCode去做。
也不是完全没有办法,最典型的就是《java Persistence with hibernate》 的例子可以参照。那种情况在文章中描述的情况以及包括了,正好说明了class文件记录了什么而又没有记录什么——一个非泛型的派生类继承一个泛型基类时,派生类的class文件对基类的记录就包含了已经确定了值了泛型参数,相对泛型基类来说,这里仍然是“声明”一侧,于是源码中泛型信息在文本怎么写的就在class文件里记录了什么。
RednaxelaFX
浏览: 2095483 次
来自: 海外
jdk8下 scanoops 时出现这个问题:Windbg E ...
Virtual Machines: Versatile Pla ...
beneo 写道发现google的java项目灰常灰长很喜欢b ...
Jefen 写道RednaxelaFX 写道.....公司网络 ...
rss?n=xxxx 这个n参数已经无效了.这是不让导出的意思 ...您所在的位置: &
详解Java泛型type体系整理
详解Java泛型type体系整理
JavaEye博客
一直对jdk的ref使用比较模糊,早上花了点时间简单的整理了下,也帮助自己理解一下泛型的一些处理。
一直对jdk的ref使用比较模糊,早上花了点时间简单的整理了下,也帮助自己理解一下泛型的一些处理。
java中class,method,field的继承体系
498)this.width=498;' onmousewheel = 'javascript:return big(this)' height=325 alt="" src="/files/uploadimg/4250.png" width=540>
java中所有对象的类型定义类Type
498)this.width=498;' onmousewheel = 'javascript:return big(this)' height=191 alt="" src="/files/uploadimg/4251.png" width=540>
Type : Type is the common superinterface for all types in the Java programming language. These include raw types, parameterized types, array types, type variables and primitive types.
一般我们不直接操作Type类型,所以第一次使用会对这个比较陌生,相对内部的一些概念。
根据Type类型分类,整理了一个type -> class的转换过程,同理也包括处理Generic Type。支持多级泛型处理。
private&static&Class&getClass(Type&type,&int&i)&{&&& &&&&&&&&&if&(type&instanceof&ParameterizedType)&{&&&&&&&&&&&&&&return&getGenericClass((ParameterizedType)&type,&i);&&& &&&&&&&&&}&else&if&(type&instanceof&TypeVariable)&{&&& &&&&&&&&&&&&&return&(Class)&getClass(((TypeVariable)&type).getBounds()[0],&0);&&&&&&&&&&}&else&{&&&&&&&&&&&&&return&(Class)&&&& &&&&&&&&&}&&& &&&&&}&&& &&& &&&&&private&static&Class&getGenericClass(ParameterizedType&parameterizedType,&int&i)&{&&& &&&&&&&&&Object&genericClass&=&parameterizedType.getActualTypeArguments()[i];&&& &&&&&&&&&if&(genericClass&instanceof&ParameterizedType)&{&&&&&&&&&&&&&&return&(Class)&((ParameterizedType)&genericClass).getRawType();&&& &&&&&&&&&}&else&if&(genericClass&instanceof&GenericArrayType)&{&&&&&&&&&&&&&&return&(Class)&((GenericArrayType)&genericClass).getGenericComponentType();&&& &&&&&&&&&}&else&if&(genericClass&instanceof&TypeVariable)&{&&&&&&&&&&&&&&return&(Class)&getClass(((TypeVariable)&genericClass).getBounds()[0],&0);&&& &&&&&&&&&}&else&{&&& &&&&&&&&&&&&&return&(Class)&genericC&&& &&&&&&&&&}&&& &&&&&}&& &
测试代码:
interface&GeneircInteface&{&&& &&& &&&&&T&method1(T&obj);&&& &}&&& &&& &interface&CommonInteface&{&&& &&& &&&&&Integer&method2(Integer&obj);&&& &}&&& &&& &class&BaseGeneircInteface&implements&GeneircInteface&{&&& &&& &&&&&protected&R&&&& &&& &&&&&@Override&& &&&&&public&R&method1(R&obj)&{&&& &&&&&&&&&return&&&& &&&&&}&&& &&& &}&&& &&& &class&GenericClass&extends&BaseGeneircInteface<LIST>&implements&GeneircInteface<LIST>,&CommonInteface&{&&& &&& &&&&&@Override&& &&&&&public&List&method1(List&obj)&{&&& &&&&&&&&&result&=&&&& &&&&&&&&&return&&&& &&&&&}&&& &&& &&&&&public&Integer&method2(Integer&obj)&{&&& &&&&&&&&&return&&&& &&&&&}&&& &&& &&&&&public&<T,&E&extends&Throwable>&T&method3(T&obj)&throws&E&{&&& &&&&&&&&&return&&&& &&&&&}&&& &&& &}&& &
针对class的泛型接口使用:
private&static&void&classGeneric()&{&&& &&&&&&&&&System.out.println("\n---------------------&classGeneric&---------------------");&&& &&&&&&&&&GenericClass&gc&=&new&GenericClass();&&& &&&&&&&&&Type[]&gis&=&gc.getClass().getGenericInterfaces();&&&&&&&&&&Type&gps&=&gc.getClass().getGenericSuperclass();&&&&&&&&&&TypeVariable[]&gtr&=&gc.getClass().getTypeParameters();&&&&&&&&&&System.out.println("==============&getGenericInterfaces");&&& &&&&&&&&&for&(Type&t&:&gis)&{&&& &&&&&&&&&&&&&System.out.println(t&+&"&:&"&+&getClass(t,&0));&&& &&&&&&&&&}&&& &&&&&&&&&System.out.println("==============&getGenericSuperclass");&&& &&&&&&&&&System.out.println(getClass(gps,&0));&&& &&&&&&&&&System.out.println("==============&getTypeParameters");&&& &&&&&&&&&for&(TypeVariable&t&:&gtr)&{&&& &&&&&&&&&&&&&StringBuilder&stb&=&new&StringBuilder();&&& &&&&&&&&&&&&&for&(Type&tp&:&t.getBounds())&{&&& &&&&&&&&&&&&&&&&&stb.append(tp&+&"&:&");&&& &&&&&&&&&&&&&}&&& &&& &&&&&&&&&&&&&System.out.println(t&+&"&:&"&+&t.getName()&+&"&:&"&+&stb);&&& &&&&&&&&&}&&& &&& &&&&&}&& &
针对method的泛型接口使用:
private&static&void&methodGeneric()&throws&Exception&{&&& &&&&&&&&&System.out.println("\n---------------------&methodGeneric&---------------------");&&& &&&&&&&&&GenericClass&gc&=&new&GenericClass();&&& &&&&&&&&&Method&method3&=&gc.getClass().getDeclaredMethod("method3",&new&Class[]&{&Object.class&});&&& &&& &&&&&&&&&Type[]&gpt3&=&method3.getGenericParameterTypes();&&& &&&&&&&&&Type[]&get3&=&method3.getGenericExceptionTypes();&&& &&&&&&&&&Type&gt3&=&method3.getGenericReturnType();&&& &&&&&&&&&System.out.println("==============&getGenericParameterTypes");&&& &&&&&&&&&for&(Type&t&:&gpt3)&{&&& &&&&&&&&&&&&&System.out.println(t&+&"&:&"&+&getClass(t,&0));&&& &&&&&&&&&}&&& &&&&&&&&&System.out.println("==============&getGenericExceptionTypes");&&& &&&&&&&&&for&(Type&t&:&get3)&{&&& &&&&&&&&&&&&&System.out.println(t&+&"&:&"&+&getClass(t,&0));&&& &&&&&&&&&}&&& &&&&&&&&&System.out.println("==============&getType");&&& &&&&&&&&&System.out.println(gt3&+&"&:&"&+&getClass(gt3,&0));&&& &&&&&}&& &
针对field的泛型接口使用:
private&static&void&fieldGeneric()&throws&Exception&{&&& &&&&&&&&&System.out.println("\n---------------------&fieldGeneric&---------------------");&&& &&&&&&&&&GenericClass&gc&=&new&GenericClass();&&& &&&&&&&&&Field&field&=&gc.getClass().getSuperclass().getDeclaredField("result");&&& &&& &&&&&&&&&Type&gt&=&field.getGenericType();&&& &&&&&&&&&Type&ft&=&field.getType();&&& &&&&&&&&&System.out.println("==============&getGenericType");&&& &&&&&&&&&System.out.println(gt&+&"&:&"&+&getClass(gt,&0));&&& &&&&&&&&&System.out.println("==============&getType");&&& &&&&&&&&&System.out.println(ft&+&"&:&"&+&getClass(ft,&0));&&& &&&&&}&& &
输出结果:
---------------------&classGeneric&---------------------&&& &==============&getGenericInterfaces&&& &com.agapple.misc.GeneircInteface<JAVA.UTIL.LIST>&:&interface&java.util.List&&& &interface&com.monInteface&:&interface&com.monInteface&&& &==============&getGenericSuperclass&&& &interface&java.util.List&&& &==============&getTypeParameters&&& &&& &---------------------&fieldGeneric&---------------------&&& &==============&getGenericType&&& &R&:&class&java.lang.Object&&& &==============&getType&&& &class&java.lang.Object&:&class&java.lang.Object&&& &&& &---------------------&methodGeneric&---------------------&&& &==============&getGenericParameterTypes&&& &T&:&class&java.lang.Object&&& &==============&getGenericExceptionTypes&&& &E&:&class&java.lang.Throwable&&& &==============&getType&&& &T&:&class&java.lang.Object&&&
结果说明:
因为泛型的擦拭,对应的GeneircInteface和BaseGeneircInteface,在源码信息已被擦除对应的类型,进行了upper转型,所以取到的是Object。可以使用extends
GenericClass在类定义时,声明了继承父接口的泛型为List,所以再通过接口和父类获取泛型信息时,是能正确的获取。通过javap -v可以获取对应的class信息
const&#46&=&Asciz&&&Lcom/agapple/misc/BaseGeneircInteface<LJAVA lang="" util List;>;Lcom/agapple/misc/GeneircInteface<LJAVA lang="" util List;>;Lcom/agapple/misc/CommonI;&&& &
而在GenericClass中定义的方法method3,在class信息是一个被向上转型后擦拭的信息。所以获取method3的相关泛型信息是没有的。
method3;&&& &const&#36&=&Asciz&&&(Ljava/lang/O)Ljava/lang/O;&&& &const&#37&=&Asciz&&&E&&& &const&#38&=&class&&&#39;&&&&&const&#39&=&Asciz&&&java/lang/T&&& &const&#40&=&Asciz&&&(TT;)TT;^TE;;&&& &const&#41&=&Asciz&&&TT;;&& &
思考问题:
List list = new ArrayList(); 是否有获取对应的String泛型信息? 不能,临时变量不能保存泛型信息到具体class对象中,List和List对应的class实体是同一个。
GeneircInteface&gi&=&new&GeneircInteface()&{&&& &&& &&&&&&&&&&&&&@Override&& &&&&&&&&&&&&&public&Integer&method1(Integer&obj)&{&&& &&&&&&&&&&&&&&&&&return&1;&&& &&&&&&&&&&&&&}&&& &&& &&&&&&&&&};&& &
通过匿名类的方式,是否可以获取Integer的泛型信息? 能,匿名类也会在进行class compiler保存泛型信息。
假如本文例子中的method3,是放在父类中BaseGeneircInteface中进行申明,GenericClass中指定R为List,是否可以获取到对应的泛型信息? 不能,理由和问题1类似。
具体泛型擦拭和信息保存,引用了撒迦的一段回复,解释的挺详尽了。
RednaxelaFX 写道
Java泛型有这么一种规律:
位于声明一侧的,源码里写了什么到运行时就能看到什么;
位于使用一侧的,源码里写什么到运行时都没了。
什么意思呢?“声明一侧”包括泛型类型(泛型类与泛型接口)声明、带有泛型参数的方法和域的声明。注意局部变量的声明不算在内,那个属于“使用”一侧。
Java代码import&java.util.L&&&& &import&java.util.M&&&& &&& &public&class&GenericClass&{&&private&List&&&private&Map&&&&& &public&&U&genericMethod(Map&m)&{&&return&null;&&&& &}&&&& &}&&& &
上面代码里,带有注释的行里的泛型信息在运行时都还能获取到,原则是源码里写了什么运行时就能得到什么。针对1的GenericClass,运行时通过Class.getTypeParameters()方法得到的数组可以获取那个“T”;同理,2的T、3的java.lang.String与T、4的T与U都可以获得。
这是因为从Java 5开始class文件的格式有了调整,规定这些泛型信息要写到class文件中。以上面的map为例,通过javap来看它的元数据可以看到记录了这样的信息:
Javap代码private&java.util.Map&&&&& &Signature:&Ljava/util/M&&&& &Signature:&length&=&<FONT color=#c&&&& &00&0A&&& &
乍一看,private java.util.M不正好显示了它的泛型类型被擦除了么?
但仔细看会发现有两个Signature,下面的一个有两字节的数据,0x0A。到常量池找到0x0A对应的项,是:
Javap代码const&#10&=&Asciz&Ljava/util/Map;;&&&&
也就是内容为“Ljava/util/M”的一个字符串。
根据Java 5开始的新class文件格式规范,方法与域的描述符增添了对泛型信息的记录,用一对尖括号包围泛型参数,其中普通的引用类型用“La/b/c/D;”的格式记录,未绑定值的泛型变量用“T”的格式记录,其中xxx就是源码中声明的泛型变量名。类型声明的泛型信息也以类似下面的方式记了下来:
Javap代码public&class&GenericClass&extends&java.lang.Object&&&& &Signature:&length&=&<FONT color=#c&&&& &00&12&&&& &&const&#18&=&Asciz&Ljava/lang/O;&&&&
详细信息请参考官方文档:/docs/books/jvms/second_edition/ClassFileFormat-Java5.pdf
相比之下,“使用一侧”的泛型信息则完全没有被保留下来,在Java源码编译到class文件后就确实丢失了。也就是说,在方法体内的泛型局部变量、泛型方法调用之类的泛型信息编译后都消失了。
Java代码import&java.util.ArrayL&&&& &import&java.util.L&&&& &&& &public&class&TestClass&{&&&& &public&static&void&main(String[]&args)&{&&&& &List&list&=&null;&&list&=&new&ArrayList();&&for&(int&i&=&0;&i&<&10;&i++)&;&&&& &}&&&& &}&&&
上面代码中,1留下的痕迹是:main()方法的StackMapTable属性里可以看到:
Java代码StackMapTable:&number_of_entries&=&2&&&& &frame_type&=&<FONT color=#c&&&&& &offset_delta&=&12&&&& &locals&=&[&class&java/util/List,&int&]&&&& &frame_type&=&<FONT color=#c&&&&& &offset_delta&=&11&&& &
但这里是没有留下泛型信息的。这段代码只所以写了个空的for循环就是为了迫使javac生成那个StackMapTable,让1多留个影。
如果main()里用到了list的方法,那么那些方法调用点上也会留下1的痕迹,例如如果调用list.add("");,则会留下“java/util/List.add:(Ljava/lang/O)Z”这种记录。
2留下的是“java/util/ArrayList."":()V”,同样也丢失了泛型信息。
由上述讨论可知,想对带有未绑定的泛型变量的泛型类型获取其实际类型是不现实的,因为class文件里根本没记录实际类型的信息。觉得这句话太拗口的话用例子来理解:要想对java.util.List获取E的实际类型是不现实的,因为List.class文件里只记录了E,却没记录使用List时E的实际类型。
想对局部变量等“使用一侧”的已绑定的泛型类型获取其实际类型也不现实,同样是因为class文件中根本没记录这个信息。例子直接看上面讲“使用一侧”的就可以了。
知道了什么信息有记录,什么信息没有记录之后,也就可以省点力气不去纠结“拿不到T的实际类型”、“建不出T类型的数组”之类的问题了orz
【编辑推荐】
【责任编辑: TEL:(010)】
关于的更多文章
IE浏览器不支持很多CSS属性是出了名的,即便在支持的部分中,也
随着云计算、物联网、大数据、移动互联网的大发展,你应该知道这些。
程序员的30岁,是个伤不起的现象。你不可能敲一辈子的
Hadoop Summit 2013 大会讲师 PPT 第二季重磅来袭!如
现在这天气到处都是高温,还是老老实实的呆在家里上网
本书是一本从头至尾都使用现实世界例子讲述有关编写Web应用程序的书籍。WebWork所强调的内容是:利用框架实现你的项目,而不是被
51CTO旗下网站JAVA 泛型接口和泛型方法 - 那些年我们一起上过的项目 - ITeye博客
博客分类:
泛型也可以应用于接口,例如生成器,一种专门负责创建对象的类。这其实是工厂方法设计模式的一种应用。不过使用生成器创建对象时,不需要参数。而工厂方法一般是需要参数的。
package tik4.
public interface Generator&T& {
一个Fibonacci数列实现
package tik4.
public class Fibonacci implements Generator&Integer& {
// 参数类型用Integer,使用int将不能编译
// public int next() {
// return 0;
public Integer next() {
return fib(count++);
private int fib(int n) {
if (n & 2) return 1;
return fib(n - 2) + fib(n - 1);
public static void main(String[] args) {
Fibonacci gen = new Fibonacci();
for (int i = 0; i &= 17; i++)
System.out.print(gen.next() + " ");
* Output: 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
可以在类中包含参数化方法,而这个方法所在的类可以是泛型类,也可以不是泛型类。是否拥有泛型方法,和所在的类是否泛型没有关系。泛型方法使得该方法能够独立于类而产生变化。以下是一个基本原则:如果泛型方法可以取代整个类的泛型化,就应该只使用泛型方法。另外,对于一个static方法而言,无法访问泛型
类的参数类型,所以static方法需要使用泛型能力,就必须成为泛型方法
package tik4.
public class GenericMothod {
public &T,M,N& void getTType(T t,M m,N n){
* 传入int,long ,double等基本类型时,自动打包机制
* 会将基本类型包装成相应的对象
System.out.println(t.getClass().getName());
System.out.println(m.getClass().getName());
System.out.println(n.getClass().getName());
public static void main(String[] args) {
//泛型类在创建对象时必须指定参数类型,而泛型方法则不需要在创建对象时指定参数类型T
GenericMothod gm = new GenericMothod();
gm.getTType("", 1, 1.0);
gm.getTType(1.0F, 'c', gm);
java.lang.String
java.lang.Integer
java.lang.Double
java.lang.Float
java.lang.Character
tik4.generic.GenericMothod
利用参数类型推断
问题:很烦这种写法是不是,老子在声明变量的的时候已经指明了参数类型,为毛还要在初始化对象时再指定?
Map&Integer, List&? extends Set&String&&& map =
new HashMap&Integer, List&? extends Set&String&&&();
解决:搞一个工具类
package tik4.
import java.util.HashM
import java.util.L
import java.util.M
import java.util.S
public class New {
public static &K, V& Map&K, V& hashMap() {
return new HashMap&K, V&();
public static void main(String[] args) {
Map&Integer, List&? extends Set&String&&& map = New.hashMap();
类型推断只对赋值操作有效,其他时候不起作用。如果你使用泛型方法调用的结果(例如:New.hashMap())作为参数,传递给其他方法,此时编译器不会执行类型推断。编译器认为,调用泛型方法之后,其返回值被赋给一个Object类型的变量。上代码:
package tik4.
import java.util.L
import java.util.M
import java.util.S
public class LimitsOfInference {
static void f(Map&Integer, List&? extends Set&String&&& map){};
public static void main(String[] args) {
* the mothed f(Map&Integer, List&? extends Set&String&&&
* is not applicable for arguments (Map&Object,Object&)
* 不能编译
f(New.hashMap());
显示类型说明?? think in java4中是这么写的,但是我的机器上不能编译,难道书上是在扯淡
在泛型方法中,可以显示的指定参数类型。在 点操作符 和 方法名之间插入尖括号,然后将类型置于括号内。如果是在定义该方法的类的内部,则在点操作符之前使用this关键字如果使用static方法,必须在点操作符之前加上类名。这种语法,可以解决LimitsOfInference.java中的问题。
package tik4.
import java.util.L
import java.util.M
import java.util.S
public class ExplicitTypeSpecification {
static void f(Map&Integer, String& map){};
public static void main(String[] args) {
//java 5和java6 中均不能编译。
f(New.&Map&Integer, String&&hashMap());
泛型推导在java7中已经实现了。
List&String& list = new ArrayList&&();
因为编译器可以从前面(List)推断出推断出类型参数,所以后面的ArrayList之后可以不用写泛型参数了,只用一对空着的尖括号就行。当然,你必须带着”菱形”&&,否则会有警告的。
Java SE7 只支持有限的类型推断:只有构造器的参数化类型在上下文中被显著的声明了,你才可以使用类型推断,否则不行。 看代码:
List&String& list = new ArrayList&&();
list.add("A");
//这个不行
list.addAll(new ArrayList&&());
// 这个可以
List&? extends String& list2 = new ArrayList&&();
list.addAll(list2);
浏览 13086
浏览: 64252 次
来自: 北京
这样的帖子必须手动来赞一个!
顶一发,字数补丁。字数补丁。字数补丁。字数补丁。字数补丁。字数 ...
北斗文昌 写道引用也就是说,String subStr = b ...
引用也就是说,String subStr = bigStrin ...
以前还这么看过 substring这块。。。。
刚刚看了一下 ...

我要回帖

更多关于 下限泛型类方法 的文章

 

随机推荐