Java泛型和设计模式:不参数化泛型类型的引用总是一件坏事? [英] Java generics and design patterns: not parameterizing a reference to a generic type is always a bad thing?

查看:223
本文介绍了Java泛型和设计模式:不参数化泛型类型的引用总是一件坏事?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题部分与我最后的问题< a>。



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

  public interface MyObject< N extends Number> {} 

public interface MyCollecion< N extends Number> {
public foo(MyObject< N> obj)
}

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

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


泛型集合应该这样构造:

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

MyCollection< MyObject< Double>> c = f。< Double> createCell(MyType);

public void buildIntegerCollection(){...}
}



好的,因为这里一切都好。 CollectionBuilder知道什么是通用的具体类型来指定(在这种情况下双),并可以正确构建。我可以编译这个没有警告,所有应该工作正常。



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

我的应用程序中有另一个类需要使用由CollectionBuilder构建的集合(我们称之为这个类UserClass)。
UserClass:


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

在描述的情况下,是不是一个坏主意不参数泛型类MyCollection insied UserClass?

  public UserClass {
MyCollection a; //警告
MyCollection<?> b; //没有警告

公共方法(MyObject o){//警告
a.foo(b); //编译
}
public method2(MyObject<?> o){
b.foo(o); //错误不会编译
}
}

Java编译器总是抗议如果我不指定通用参数,则会发出警告。无论如何,从UserClass内部我不知道具体参数(我想不知道它),甚至用?声明它。不允许我在MyCollection上调用foo方法。



所以问题是:

$ ol

  • 不参数化泛型类型的引用总是一件坏事? 如果1处的回答为否,这是不是正确的情况? 如果1处的答案为YES,那么如何在不知道泛型类型的情况下使用UserClass中的MyCollection方法?

  • 我的设计不好吗?

  • 我希望已经清楚。我一直在努力解决这个问题,我不知道。请帮助我。

    解决方案


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

      根据与其相关联的对象类型对 Class >进行参数化的想法总是感觉有点首先是可疑的,对我来说。 Class 的要点是有一个通用接口,可用于获取有关任何Object(ala reflection)的信息,而不管其类型如何。

      但我离题了。根据Java编译器和泛型类型的实现者,即使您仅使用<?> ,您也应该始终参考您的引用。


    2. 不适用。虽然你总是可以不声明任何类型信息,然后使用 @SuppressWarnings(unchecked)以及一个明确的强制类型转换,以使编译器开心。


    3. 请参阅Bohemian的答案。

    4. 没有足够的信息可以说。虽然我的头脑不高,但我不确定实际使用情况对于代表通用对象集合的泛型类是什么。为什么不直接使用集合?


    this question is partially related to my last question.

    I have a generic class representing a collection of generic objects:

    public interface MyObject<N extends Number>{}
    
    public interface MyCollecion<N extends Number> {
        public foo(MyObject<N> obj)
    }
    

    In my design these collections of objects are constructed by a client class (let's call it CollectionBuilder) through an abstract class approach:

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

    Generic collections should be constructed this way:

    public class CollectionBuilder{
        AbstractCollectionFactory f;
        public void buildDoubleCollection(){
    
             MyCollection<MyObject<Double>> c = f.<Double>createCell("MyType");
        }
        public void buildIntegerCollection(){...}
    }
    

    Ok.Since here all ok. CollectionBuilder is aware of what is the generic concrete type to specify (Double in this case) and can build correctly. I can compile this with no warning and all should work fine.

    Now I have a question related both to generics and the design of my program.

    I have another class in my application that need to use the collection built by CollectionBuilder (let's call this class UserClass). The UserClass:

    1. Doesn't need to know of which particular concrete type are its collection (MyCollection<MyObject<Double>> or MyCollection<MyObject<Integer>>).
    2. perform some operations on these collections invoking some methods defined in MyCollection interface.
    3. I would not want to add a generic type to it.

    In the situation described, is that a bad idea do not parametrize the generic class MyCollection insied 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
         }
    }
    

    Java compiler always protest with a warning if I don't specify the generic parameter. Anyway from inside UserClass I don't know the concrete parameter (and I would like to don't know it) and even declaring it with "?" don't allow me to call method foo on MyCollection.

    So the question are:

    1. not parameterizing a reference to a generic type is always a bad thing?
    2. if answer at 1 is NO, is this a right situation for not doing it?
    3. if answer at 1 is YES, how can I use MyCollection method from inside UserClass without knowing their generic types?
    4. Is mine a bad design ?

    I hope to have been clear. I've be struggling on this problem from days, and I have no idea. Please help me.

    解决方案

    1. According to the Java compiler, yes. And this answer contains a lot of good points as to why. Personally I disagree in some situations, especially where the use of Class is concerned (like for instance, if you have a Map<Class, Object>). In such cases having to always tack <?> on to the end of "Class" just feels like needless tedium, and does not make the code any more readable.

      The idea of having Class be parameterized based upon what type of Object it is associated with has always felt a bit dubious in the first place, to me. The point of Class is to have a common interface that can be used to obtain information about any Object (ala reflection), regardless of its type.

      But I digress. According to the Java compiler and the implementors of generic types, you should always parameterize your reference, even if you are only using <?>.

    2. Not applicable. Though you can always not declare any type information, and then use @SuppressWarnings("unchecked") along with an explicit cast to make the compiler happy.

    3. See Bohemian's answer.

    4. There's not really enough information to say. Though off the top of my head, I'm not sure what the actual use-case would be for having "a generic class representing a collection of generic objects". Why not just use the collections directly?

    这篇关于Java泛型和设计模式:不参数化泛型类型的引用总是一件坏事?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆