最近在学习Thinking in Java 泛型的章节,关于泛型接口的具体应用; 生成器(generator)就是一个很好的例子,它是一种专门负责创建对象的类,是工厂方法设计模式的一种具体应用,下面看一下具体的实现 :
一般而言,一个生成器只定义一个方法,用来产生新的对象 :
public interface Generator<T> { T next();}
方法 next() 返回类型是参数化的T,从这里看,接口使用泛型和类使用泛型并没有区别;
为了实现Generator接口,我们还需要一些别的类. StoryCharacter层次如下 :
public static class StoryCharacter{
private static int counter = 0;
private final int id = counter ++;
@Override
public String toString() {
return getClass().getSimpleName() + " " + id;
}
}
public static class GoodGuy extends StoryCharacter {}
public static class LukeSkywalker extends GoodGuy {}
public static class Yoda extends GoodGuy {}
public static class BadGuy extends StoryCharacter {}
public static class DarthVader extends BadGuy {}
public static class JabbaTheHut extends BadGuy {}
现在,我们可以编写一个类,实现Generator 接口
public static class StoryCharacterGenerator implements DemoSix.Generator<StoryCharacter>,Iterable<StoryCharacter>{
Random rand = new Random(47);
private Class[] types = {GoodGuy.class,LukeSkywalker.class,Yoda.class,BadGuy.class,DarthVader.class,JabbaTheHut.class};
public StoryCharacterGenerator() {
}
private int sz;
public StoryCharacterGenerator(int sz) {
this.sz = sz;
}
@Override
public StoryCharacter next() {
try {
return (StoryCharacter)types[rand.nextInt(types.length)].newInstance();
} catch (Exception e) {
throw new UnsupportedOperationException();
}
}
class StoryCharacterIterator implements Iterator<StoryCharacter> {
int count = sz;
@Override
public boolean hasNext() { return count > 0; }
@Override
public StoryCharacter next() {
count--;
return StoryCharacterGenerator.this.next();
}
@Override
public void remove() { // Not implemented
throw new UnsupportedOperationException();
}
}
@Override
public Iterator<StoryCharacter> iterator() {
return new StoryCharacterIterator();
}
public static void main(String[] args) {
StoryCharacterGenerator gen = new StoryCharacterGenerator();
for(int i = 0; i < 5; i++){
System.out.println(gen.next());
}
for(StoryCharacter s : new StoryCharacterGenerator(5)){
System.out.println(s);
}
}
}
运行程序打印结果如下 :
参数化的Generator 接口确保 next() 的返回值是参数的类型 ; StoryCharacterGenerator 同时还实现了Iterable接口,所以它可以在循环语句中使用,在第二个构造器中实现了 " 末端哨兵 "来判断停止条件;
以上就是泛型接口实现生成器,我们可以在这个上面进一步做一下扩展,来实现一个通用的类型生成器,首先写一个基础的生成器 :
public static class BasicGenerator<T> implements DemoSix.Generator<T>{
private Class<T> type;
public BasicGenerator(Class<T> type) {
this.type = type;
}
@Override
public T next() {
try {
return type.newInstance();
} catch (Exception e) {
throw new RuntimeException();
}
}
public static <T> DemoSix.Generator<T> create(Class<T> type){
return new BasicGenerator<T>(type);
}
}
在BasicGenerator这个类中我们已提供了基本实现,BasicGenerator这个类必须具备两个特点 :
1. 它必须声明为public (要处理的类在不同包中,所以使用最大访问权限修饰符)
2. 它必须具备默认的构造器(无参构造器) . 要创建这样的BasicGenerator对象,只需调用他的 create() 方法,并传入想要生成的类型,泛型化的 create() 方法允许执行BasicGenerator.create(MyType.class),而不必执行麻烦的new BasicGenerator< MyType >(MyType.class)
下面是一个具有默认构造器的简单的类 :
public static class CountedObject{
private static long counter = 0;
private final long id = counter++;
public long id(){return id;}
@Override
public String toString() {
return "CountedObject " + id;
}
}
使用BasicGenerator,可以很容易的为CountedObject创建一个Generator
public static void main(String[] args) {
DemoSix.Generator<CountedObject> gen = BasicGenerator.create(CountedObject.class);
for (int i = 0; i < 5; i++) {
System.out.println(gen.next());
}
}
输出结果
可以看到,使用泛型方法创建Generator对象,大大减少了我们要编写的代码. Java泛型要求传入Class对象,以便也可以在create()方法中用它进行类型推断.
以上就是一个通用的泛型生成器,学习内容来自编程思想