实现一个通用的泛型生成器Generator 贺兰的博客

最近在学习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()方法中用它进行类型推断.
以上就是一个通用的泛型生成器,学习内容来自编程思想

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值