Java泛型(续)首先对上次的泛型做一些补充说明 1.<? extends Class>是一种限制通配符类型,它可以接受所有<Class>以及Class的子类型。然而调用代价是,只读访问。
2.TClass<T> { }
这个T是不能拿来实例化对象的,只能用来进行转型,和限定参数类型和返回类型。
3.关于静态方法的泛型 public static <T> T gMethod (List<T> list) { ... }
e.g. public class Circle {
public static <T> T gMethod(List<T> list) { System.out.println("come here"); return list.get(0); }
public static void main(String args[]) { List<Person> pl = new LinkedList<Person>(); pl.add(new Person("sharkmao",622)); Person p = Circle.gMethod(pl); } }
4.一个BT的语法 <T extends Object & Comparable<? super T>> T max (Collection<? extends T> coll) {} C++中的泛型已经相当恶心了,没有想到java中的泛型也没有好到哪里去。 T必须实现Comparable接口,而且Comparable接口比较的类型必须是T的超类 e.g. public abstract class Shape implements Comparable<Shape>{}
LinkedList<Shape> sList = new LinkedList<Shape>(); Shape s = Collections.max(sList);
之所以比较的是Shape的超类,是因为這是合理的,因为不知道比较出来的结果会是Rect或Circle或Stroke但无论如何它们都可以向上转型为Shape。
下面说说java泛型中擦拭这个概念。
江南白衣blog的回复中有这么一个例子 import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type;
import junit.framework.TestCase;
class TClass<T> { }
class GoodClass<T> extends TClass<String> { public ParameterizedType getClassT() { return (ParameterizedType) getClass().getGenericSuperclass(); } }
class BadClass<T> extends TClass<T> { public ParameterizedType getClassT() { return (ParameterizedType) getClass().getGenericSuperclass(); } }
public class GenericsTest extends TestCase {
private void print(Type[] targs) { System.out.print("actual type arguments are:"); for (int j = 0; j < targs.length; j++) { System.out.print(" instance of " + targs[j].getClass().getName() + ":"); System.out.println(" (" + targs[j] + ")"); } }
public void testGoodClass() throws Exception { ParameterizedType type = new GoodClass<String>().getClassT(); Type[] types = type.getActualTypeArguments(); print(types);
assertEquals(TClass.class, type.getRawType()); assertEquals(String.class, types[0]); }
/*public void testBadClass() throws Exception { ParameterizedType type = new BadClass<String>().getClassT(); Type[] types = type.getActualTypeArguments(); print(types);
assertEquals(TClass.class, type.getRawType()); assertEquals(String.class, types[0]); }*/ }
注意GoodClass和BadClass唯一的不同就是在继承的时候一个指定了父亲的类型是String,而另一个没有指定父亲的类型。 但是测试testBadClass方法会失败。 下面是一段对擦拭这个概念阐述的一段话 实际上BadClass<String>()实例化以后Class里面就不包括T的信息了,对于Class而言T已经被擦拭为Object。而真正的T参数被转到使用T的方法(或者变量声明或者其它使用T的地方)里面(如果没有那就没有存根,这里指ParameterizedTyp),所以无法反射到T的具体类别,也就无法得到T.class。 就我目前的理解,一个使用了泛型的类是无法得到自己的T.class的,只有它的子类在继承的时候,为父类指定T的类型(当然父类中有Class<T>clazz这个属性),然后子类中就才可以获得并且使用这个类型。
后来看了一些对java泛型的评论 Java的范型实现来自于一个叫做Pizza的项目。后来呢改名叫做GJ,再后来通过JSR被融合进Java语言。由于Java的范型实现中有一个重要的设计目标,即使范型实现能够运行于现有的、未经修改的JVM上。不修改JVM当然看上去很美,但也会带来一大堆稀奇古怪的限制。 |
|