DarkMatter in Cyberspace
  • Home
  • Categories
  • Tags
  • Archives

Java范型方法中T与?的比较


Java范型从范围上分,有范型类和范型方法两种,这里只讨论范型方法,从语义上来说,范型中的 T 和 ? 都有“任意一个类”(或者“任意一种类型”)的意思,那么二者的区别是什么呢?我认为是 T 可以放在Field或者Method名称前作为类型名,而 ? 不行,除此之外本质上完全一样,下面的代码是一个实例。

package org.leechau.genericEx;

import java.util.ArrayList;

import org.junit.Before;

import org.junit.Test;

public class GenericTest {

private final ArrayList p1 = new ArrayList();

private final ArrayList p2 = new ArrayList();

public String ma(ArrayList pa) {

return pa.get(0).toString();

}

public String mb(ArrayList <?> pa) {

return pa.get(0).toString();

}

@Before

public void setUp() throws Exception {

p1.add("1st strings");

p2.add(51);

}

@Test

public void testMa() {

System.out.println(ma(p1));

System.out.println(ma(p2));

}

@Test

public void testMb() {

System.out.println(mb(p1));

System.out.println(mb(p2));

}

}

下面的代码演示了如何分别用 T 和 ? 完成相同的实现。

T版:

package org.leechau.genericEx;

import java.util.Collection;

public abstract class Animal {

public void playWith(Collection playGroup) {}

}

package org.leechau.genericEx;

import java.util.ArrayList;

import java.util.Collection;

public class Dog extends Animal {

@Override

public void playWith(Collection playGroup) {

System.out.println(this.toString() + " play with "

  • playGroup.toString());

}

public static void main(String[] args) {

Collection dogs = new ArrayList();

Dog aDog = new Dog();

aDog.playWith(dogs);

}

}

?版:

package org.leechau.genericEx;

import java.util.Collection;

public class Animal2 {

public void playWith(Collection <? extends Animal2> playGroup) {}

}

package org.leechau.genericEx;

import java.util.ArrayList;

import java.util.Collection;

public class Dog2 extends Animal2 {

@Override

public void playWith(Collection<? extends Animal2> playGroup) {

System.out.println(this.toString() + " play with "

  • playGroup.toString());

}

public static void main(String[] args) {

Collection dogs = new ArrayList();

Dog2 aDog = new Dog2();

aDog.playWith(dogs);

}

}

Java的范型(尤其是实现机制)给我的感觉是不够优雅,当一堆<>嵌套在一起的时候让人觉得像天书一样,背离了Java简洁易用的原则,但即便如此,毕竟现在Java还是产品开发(尤其是大规模产品)的主流工具,我们有必要理解它的一些细节。[1]的Part I,II 和[2]的第12章对范型的讲解比较透彻,[3]的4.3.7节则对Java范型进行了中肯的评价, [1]的Part III探讨了如何将没有范型的老代码改为有范型的新代码以保证类型安全 。

[1] Venkat Subramaniam, Generics in Java

[2] Cay S. Horstmann, Core Java. Volume I, Fundamentals, 8th ed, 2007.9

[3] Bruce A. Tate, Beyond Java, 2005.9



Published

Aug 18, 2011

Last Updated

Aug 18, 2011

Category

Tech

Tags

  • 比较 3
  • generic 1
  • Java 106

Contact

  • Powered by Pelican. Theme: Elegant by Talha Mansoor