Java泛型和设计模式:不参数化对泛型类型的引用总是一件坏事吗?

Hei*_*bug 5 java generics raw-types abstract-factory

这个问题与我的上一个问题部分相关.

我有一个表示泛型对象集合的泛型类:

public interface MyObject<N extends Number>{}

public interface MyCollecion<N extends Number> {
    public foo(MyObject<N> obj)
}
Run Code Online (Sandbox Code Playgroud)

在我的设计中,这些对象集合由客户端类(我们称之为CollectionBuilder)通过抽象类方法构造:

public interface AbstractCollectionFactory {
    public abstract <N extends Number> MyCollection<MyObject<N>> createCollection(String collectionType);

}
Run Code Online (Sandbox Code Playgroud)

通用集合应该以这种方式构造:

public class CollectionBuilder{
    AbstractCollectionFactory f;
    public void buildDoubleCollection(){

         MyCollection<MyObject<Double>> c = f.<Double>createCell("MyType");
    }
    public void buildIntegerCollection(){...}
}
Run Code Online (Sandbox Code Playgroud)

好的.从这里一切都好.CollectionBuilder知道要指定的通用具体类型(在这种情况下为Double)并且可以正确构建.我可以编译它没有任何警告,所有应该工作正常.

现在我有一个与泛型和我的程序设计有关的问题.

我的应用程序中有另一个类需要使用CollectionBuilder构建的集合(让我们调用这个类UserClass).UserClass:

  1. 不需要知道其集合(MyCollection<MyObject<Double>>MyCollection<MyObject<Integer>>)的具体类型.
  2. 对这些集合执行一些操作,调用MyCollection接口中定义的一些方法.
  3. 我不想为它添加泛型类型.

在描述的情况下,是不是一个坏主意不参数化通用类MyCollection insed UserClass?

public UserClass{
     MyCollection a;  //warning 
     MyCollection<?> b; //no warning

     public method(MyObject o){  //warning
          a.foo(b); //compile       
     }
     public method2(MyObject<?> o){
          b.foo(o); //error do not compile
     }
}
Run Code Online (Sandbox Code Playgroud)

如果我没有指定泛型参数,Java编译器总是会发出警告.无论如何从UserClass里面我不知道具体参数(我想不知道它)甚至用"?"声明它 不允许我在MyCollection上调用方法foo.

所以问题是:

  1. 不参数化泛型类型的引用总是一件坏事?
  2. 如果1的回答是否定的,这是不是这样做的正确情况?
  3. 如果1处的答案为YES,如何在不知道其泛型类型的情况下从UserClass中使用MyCollection方法?
  4. 我的设计不好吗?

我希望已经清楚了.我几天都在努力解决这个问题,我不知道.请帮我.

aro*_*oth 6

  1. 根据Java编译器,是的.而这个答案包含了很多的好点,为什么.我个人在某些情况下不同意,特别是在使用时Class(例如,如果你有Map<Class, Object>).在这种情况下,必须始终<?>坚持到"类"的末尾,感觉就像不必要的单调乏味,并且不会使代码更具可读性.

    Class基于与其相关联的对象类型进行参数化的想法在我看来总是让人感到有点可疑.关键Class是要有一个公共接口,可用于获取有关任何Object(ala反射)的信息,无论其类型如何.

    但我离题了.根据Java编译器和泛型类型的实现者,即使您只是使用,也应始终参数化您的引用<?>.

  2. 不适用.虽然您始终无法声明任何类型信息,然后@SuppressWarnings("unchecked")与显式强制转换一起使用以使编译器满意.

  3. 看波西米亚的答案.

  4. 没有足够的信息可以说.虽然不是我的头脑,但我不确定具有"代表通用对象集合的泛型类"的实际用例是什么.为什么不直接使用这些集合呢?