如图,图一是泛型接口,图二是泛型接口的实现类,图三是一个操作类的泛型方法,图四为使用 问题:为什么图四list方法在使用时,传入实现类,为什么会返回一个List集合?也就是图三的泛型方法内rsh.handler(set)为什么会返回List集合,不是说泛型不能向上转型,那怎么这个地方又可以执行呢?泛型方法的返回值不是T吗,要返回不应该返回单独的一个对象吗? 这里面的具体原理是什么? 我的两个猜测: 1.可能是在编译时,泛型先一步在向上转型的时候就已经擦除了,且擦除后的泛型方法的返回值为Object,而普通类是可以向上转型的,且List集合也是Object的子类,所以可以返回. 2.可能是jvm根据传入的实现类的实际参数类型,自己推导出了接口的泛型T实际类型为List<某某>但是这两个猜测怎么想都感觉有点问题,百度了很久也没用,跪求请大佬及老师赐教!!!!!!
根号申 发表于2018-08-06 09:06
百度知道上有个答复已经回答了你的问题。
向上转型是不需要强制转换的。
这是哪本书上的代码?
抱歉,老师,代码不是本书上的.这代码是我在网上搜问题的时候看见的......
但是老师您能不能帮我看看这个问题,那个百度答复的答案并不能帮我解决疑问...
我不明白:泛型不是说没有继承的概念吗,那为什么一个泛型接口的参数,可以传入一个实现类的泛型.
我有两个猜测:
1.可能是在编译时,泛型先一步在向上转型的时候就已经擦除了,
且擦除后的泛型方法的返回值为Object,而普通类是可以向上转型的,
且List集合也是Object的子类,所以可以返回.
2.可能是jvm自己根据传入的实现类的实际参数类型,
自己推导出了接口的泛型T实际类型为List<某某>
我觉得可能是第二个,但是我不知道我想的到底对不对....
所以,老师能不能麻烦您帮我看看,
我知道本论坛不对书本外的知识提供技术支持,但是还是希望老师您能帮忙看看
根号申 发表于2018-08-06 14:11
我没看懂你写的是什么意思,你写的1和2说的是一件事啊。我在上面已经说了向上转型不需要强制转换,泛型默认使用Object,任何对象都属于Object对象。你发的最后一段代码里,方法泛型就是两个尖括号,表示自动匹配。
public interface A<T>{ T test(); }
public class B<T> implements A<List<T>>{ public List<T> test() {...} }
public class X{ public static <T> T test(A<T> a){...} }
X.test(new B<C.class>());//编译通过,正常执行,且返回为List<C>,说明泛型方法的类型参数实例为List<C>,说明B推断出了接口的类型参数实例为List<C>,而接口又推出了泛型方法的类型参数实例为List<C>,但是在编译的时候,T都会被擦除变成Object,老师,这个理解对吗?
不对,你的描述没搞清楚“实参”、“实例”、“泛型”之间的传递关系,
再说一遍:
1. 你给的这段代码是错误的,就算补充了省略部分也是无法通过编译的。
2. 你的代码中泛型方法的形参是接口对象,但实际传入的是B对象,所以C填充了B的泛型而不是A的泛型。
3. 你的代码中B类在实现接口A的时候,就已经把接口A的泛型定位List对象了,所以B的方法就返回List。B类的T和A接口的T不是同一个。
4. 不给泛型定义任何值的时候,默认使用Object,任何对象都属于Object对象。
5. 不给泛型定义任何值的时候,默认使用Object,任何对象都属于Object对象。
6. 不给泛型定义任何值的时候,默认使用Object,任何对象都属于Object对象。
根号申 发表于2018-08-07 09:46
不对,你的描述没搞清楚“实参”、“实例”、“泛型”之间的传递关系,
再说一遍:
1. 你给的这段代码是错误的,就算补充了省略部分也是无法通过编译的。
2. 你的代码中泛型方法的形参是接口对象,但实际传入的是B对象,所以C填充了B的泛型而不是A的泛型。
3. 你的代码中B类在实现接口A的时候,就已经把接口A的泛型定位List对象了,所以B的方法就返回List。B类的T和A接口的T不是同一个。
4. 不给泛型定义任何值的时候,默认使用Object,任何对象都属于Object对象。
5. 不给泛型定义任何值的时候,默认使用Object,任何对象都属于Object对象。
6. 不给泛型定义任何值的时候,默认使用Object,任何对象都属于Object对象。
public interface A<T>{ T test(); }
public class B<T> implements A<List<T>>{ public List<T> test() {...} }
public class X{ public static <T> T test(A<T> a){...} }
X.test(new B<C>());
上面那段代码new B<>时传参写错了(C.class是错的)..这样写是能够在eclipse运行的.....
您的意思:C填充了B的泛型,而B在实现A接口的时候将A的泛型定位为了List,在使用时B类的T为C.
那么此时A接口的T为List<某类>吗?我开始以为此时这个A接口的T应该为List<C>,因为class B<T> implements A<List<T>>,但是看您后面写的,难道是List<Object>?