我们可以使用原始类型<t extends =“”someclass =“”>?</t>

时间:2015-04-10 23:08:41

标签: java generics raw-types

这是对"What is a raw type and why shouldn't we use it?"答案的肯定答复,即:

  

...总之,原始类型不应该在新代码中使用。您应该始终使用参数化类型。 ...

我不同意,“你永远不应该使用原始类型”。我认为有些情况下你可以安全地使用它。

对我来说有三种原始类型:

  1. “raw type”:具有此分配的每个类的原始实例:class Foo <T>。例如:Foo foo = new Foo()

  2. “带有extends的原始类型”:具有此分配的每个类的原始实例:class Foo <T extends SomeClass>。例如:Foo foo = new Foo()

  3. “具有扩展多边界的原始类型”:具有此分配的每个类的原始实例:class Foo <T extends SomeClass & SomeInterface1 & SomeInterface2>。例如:Foo foo = new Foo()

  4. 第二个是我认为可以安全使用的课程(class Foo <T extends SomeClass>)。我想知道是否有人发现任何问题。

    示例:

    public class Tests {
        public static void main(String... args){
            GenericClass<SomeClassWithSomeInterface> genericClass1 = new GenericClass<>();
            genericClass1.set(new SomeClassWithSomeInterface());
            genericClass1.set(new SomeExtendClass());
            genericClass1.set(new Object()); // Compile-time error: type is safe
    
            GenericClass genericClass2 = new GenericClass<>();
            genericClass2.set(new SomeClassWithSomeInterface());
            genericClass2.set(new SomeExtendClass());
            genericClass2.set(new Object()); // Compile-time error: type is safe too. Or not?
    
        }
    }
    
    class SomeClass{    
    }
    
    interface SomeInterface{
    }
    
    class SomeClassWithSomeInterface extends SomeClass implements SomeInterface{
    }
    
    class GenericClass<T extends SomeClassWithSomeInterface>{
        private T t;
    
        public void set(T t){
            this.t = t;
        }
    }
    
    class SomeExtendClass extends SomeClassWithSomeInterface{
    }
    

    在上面的示例中,genericClass1对象和genericClass2都是类型安全的。我的理解是对的?

1 个答案:

答案 0 :(得分:3)

考虑一下:

class SomeExtendingClass extends SomeClassWithSomeInterface {}
class SomeOtherExtendingClass extends SomeClassWithSomeInterface {}

class Test {
    public static void main() {
        GenericClass<SomeExtendingClass> generic1 = new GenericClass<SomeExtendingClass>();
        generic1.set(new SomeExtendingClass()); // ok
        generic1.set(new SomeOtherExtendingClass()); // error (as expected)

        GenericClass generic2 = new GenericClass<SomeExtendingClass>();
        generic2.set(new SomeExtendingClass()); // ok
        generic2.set(new SomeOtherExtendingClass()); // ok (but shouldn't be!)
    }
}