在 Java 中使用静态方法创建类型的通用实例

Creating a Generic instance of type using static method in Java

嗨,我有 generic java class

public abstract class Ref<Id> {
    private Id id;

    public Id getId() {
         return id;
    }

    public void setId(Id id) {
         this.id = id;
    }

    public static <Id> Id getValue(Ref<Id> reference) {
       return reference != null ? reference.getId() : null;
    }
}

其中

Id 只是 文字 就像 E,K,V

而且我看到了奇怪的变量创建

public class FirstClass {

public ManuId create(SecondClass second) {
 (1)    ManuId manuId = Ref.getValue(second.getManu());
        assert manuId != null;

        return manuId ;
    }
}
}

public class SecondClass {
     private ManuRef manu;
     public ManuRef getManu() {
       return manu;
     }
}

和:

public class ManuRef extends Ref<ManuId> {
}

和:

public class ManuId{}

所以问题符合标有(1)的行

   (1)  ManuId manuId = Ref.getValue(anotherObject.getRef());

我想知道为什么可以这样创建实例?为什么我们不必像这样指定 ManuId 类型 (2):

(2) ManuId manuId = Ref.<ManuId>.getValue(second.getManu());

为什么 Java 允许 (1).

PS: 这是主题的编辑版本。

首先,方法声明中的Id在class层面遮蔽了Id类型参数,所以Ref是泛型class与此关系不大。如果您只是将方法声明更改为

,则您的代码是等效的
public static <T> T getValue(Ref<T> reference) {
   return reference != null ? reference.getId() : null;
}

其次,由于该方法接受 Ref<T> 并且您为其提供 Ref<ManuId>,它理解 T 必须绑定到 ManuId。这叫做type inference.

所以,换句话说,你不需要做Ref.<ManuId>getValue(second.getManu());(尽管它完全有效)因为

  • ...类型变量不属于class,而是属于方法,所以引用Ref时不需要给类型参数class,以及
  • ...编译器通过查看您在调用时提供的参数推断类型参数。