创建通用类以传递通用类型(对象或列表)

时间:2018-09-07 06:32:46

标签: java generics

我正在尝试解决一个问题,我必须创建一个将对象或对象列表作为通用类型的类。我不想创建多个类,因为我有所有其他领域的共同点。

这是我所做的,但我不确定从长远来看是否安全。

主类。

public class TestGeneric{

    public static void main(String[] args) {

        List<Cat> cats = new ArrayList<>();
        cats.add(new Cat("Tom"));
        cats.add(new Cat("Jerry"));
        cats.add(new Cat("Billi"));

        Dog dog = new Dog("Bow");

        new Rat<>(cats).instOf();
        System.out.println();
        new Rat<>(dog).instOf();
    }
}

我要在通用对象中传递列表或单个对象的通用类。

class Rat<T> {
    private T obj ;

    public Rat(T t) {
        this.obj = t;
    }

    public void instOf() {
        if(obj instanceof Dog) {
            System.out.println((obj.getClass()).getName());
        }
        if(obj instanceof Cat) {
            System.out.println("Instance of Cat");
        }
        if(obj instanceof List) {
            for(Object object : ((List) obj).toArray()) {
                System.out.println(((Cat)object).getName());
            }
        }
    }
}

要作为单个对象或列表传递的类。

class Dog {
    private String name;

    public Dog() {}

    public Dog(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Dog [name=" + name + "]";
    }

}

另一个作为单个对象或列表传递的类。

class Cat {
    private String name;

    public Cat() {}

    public Cat(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Dog [name=" + name + "]";
    }   
}

请建议这样做是否正确OR,还有其他更好的方法吗?

2 个答案:

答案 0 :(得分:2)

简而言之:不好的主意。

单个实例可以轻松表示为具有一个条目的列表。甚至还有Collections.singletonList()库方法可以将单个对象变成列表。

您将要发明一种复杂的设计,该设计将大量知识带入该Rat类。您宁可去

  • 动物接口或基类(用于Cat / Dog中的常用方法)
  • 只需拥有Rat类,然后就可以与List<Animal>List<? extends Animal>一起使用

含义:您过度专业化了Rat类。严重的:不允许“单个对象”和列表。只需使用列表,然后(如果有的话)区分该列表中的元素数量。您的方法过于复杂,会使读者感到惊讶(以一种不好的方式)。不要那样做

答案 1 :(得分:0)

对于您提供的示例,您应提供一个Consumer<T>,以根据类型执行您想要的“工作”:

class Rat<T> {
    private T obj ;
    private Consumer<T> consumer;

    public Rat(T t, Consumer<T> consumer) {
        this.obj = t;
    }

    public void instOf() {
      consumer.accept(obj);
    }
}

然后只需传入合适的Consumer实例即可。

当然,这是假设您需要obj用于Rat类中的其他内容;如果没有,则抛弃泛型并传递一个Runnable

class Rat {
    private Runnable r;

    public Rat(Runnable r) {
        this.r = r;
    }

    public void instOf() {
      r.run();
    }
}