如何在java中实现泛型方法

时间:2013-11-29 09:38:42

标签: java generics

我需要覆盖此方法:

   @Override
   public <T> T convertValue(Object object, Class<T> clazz) 

问题是我不知道为什么。我不明白什么是<T>。我尝试重写它并用String类替换T:

   public <String> String convertValue(Object object, Class<String> clazz){
        return "a";
    }

但是这给了我错误:

Type mismatch: cannot convert from java.lang.String to String

所以现在我真的很困惑。有人可以解释一下这个并举例说明如何返回一些价值吗?

3 个答案:

答案 0 :(得分:1)

T是一个类型参数。它是一种类型的“占位符”。

您获得的错误是因为您使用String 类型参数隐藏(“隐藏”)String 类型 。您需要删除要正确解析的类型的类型参数。

另外,请注意,即使这样,您也无法覆盖此方法

    @Override
    public String convertValue(Object object, Class<String> clazz){
            return "a";
    }

A.convertValue()具有不兼容的类型签名。

这是因为,简单来说,Java要求您应该能够使用B.convertValue()的覆盖实现,只要您可以使用A.convertValue()而无需编译错误。所以你应该保留type参数,正如JB Nizet正确建议的那样。

最后,有一种强烈的怀疑,你可能不明白方法convertValue的含义。再次阅读JB Nizet的答案,因为他提供了一个直观的解释,并且一定要阅读基本的generics

答案 1 :(得分:0)

public <T> T convertValue(Object object, Class<T> clazz) 

是一种通用方法。它接受任何对象和Class实例clazz,它应该返回给定类的实例。

所以,你可以这样称呼它:

String s = foo.<String>convertValue(someObject, String.class);

或只是

String s = foo.convertValue(someObject, String.class);

感谢类型推断。

如果必须覆盖它,那么您的方法实现必须符合基本方法的约定。如果clazz参数为String.class,则只能返回String。如果clazz不是String.class,则总是返回“a”并抛出异常的实现将是,例如:

@Override
public <T> T convertValue(Object object, Class<T> clazz) {
    if (clazz == String.class) {
        return (T) "a";
    }
    else {
        throw new IllegalArgumentException("I only support String, sorry");
    }
}

答案 2 :(得分:0)

重写 The return type should be the same or a subtype of the return type declared in the original overridden method in the superclass 的规则。

所以不可能在子类中使用非泛型方法覆盖泛型方法,除非你在下面扩展时特别声明了T的类型

class A <T> {
    public T method(T a){
        return a;
    }
}

class B extends A<String> {

    @Override
    public String tell(String a){
        return a;
    }
}

但这不适用于下面的超级班级;其中T在方法级别内局部定义;和子类无法控制它。并且子类将遵循覆盖规则而失败。

class A  {
    public <T> T method(T a){
        return a;
    }
}  

另请阅读type erasure