代码之家  ›  专栏  ›  技术社区  ›  Ed Marty

用非泛型实现重写泛型方法

  •  3
  • Ed Marty  · 技术社区  · 15 年前

    我正在试用Java中的泛型,并想到这个例子。

    如果我有 ClassA<T> ,我可以用引用具体类的子类重写它,例如 ClassB extends ClassA<String> ,那么classa使用t的任何地方,classb都可以使用字符串。

    现在,忽略前面的 ClassA ClassB ,如果我有摘要 等级 ,它有一个泛型方法:

    public <T> void doSomething(T data);
    

    有什么办法让我 乙类 用一个具体的类重写它,类似于前面的例子?我已经想出了一些有效的方法,即参数化类和方法,但我想知道是否有其他方法。

    class ClassA<T> {
        public void doSomething(T data) {};
    }
    

    我不想将参数放入类中的原因是,它只是一个对该类型执行任何操作的方法,而一些子类甚至可能不想在该方法中执行任何操作,因此如果它不打算使用参数,我不需要将其放入类中。

    音符 :的所有子类 等级 是匿名类,所以这增加了乐趣。

    2 回复  |  直到 15 年前
        1
  •  11
  •   noah    15 年前

    多亏了 type erasure ,这个:

    public <T> void doSomething(T data);
    

    真正的意思是:

    public void doSomething(Object data);
    

    所以不,没有办法用更严格的参数类型重写。

    在本规范中:

    class ClassA<T> {
        public <T> void doSomething(T data) {};
    }
    

    类名中的类型参数和方法中的类型参数实际上是不同的参数。这就像在更高的范围内声明一个与变量同名的局部变量。你可以打电话 doSomething(123) 关于 ClassA<String> 因为第二个 T 对方法是局部的。

        2
  •  2
  •   Matthew Flynn    15 年前

    简而言之,答案是否定的。如果你用泛型参数定义一个方法,那么它的签名包含泛型,任何“重写”都必须与签名匹配(包含泛型)。

    无论如何,这确实是泛型的一个糟糕的用法,因为您所写的在语义上与

    public void doSomething(Object data) {}
    

    一般位不会给您带来多大的好处,除非它被用于指示返回值,如:

    public <T> T doSomething(T data) {}
    

    但为什么要麻烦呢?泛型调用dosomething()真的有问题吗?