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

时间:2015-01-19 13:41:02

标签: java generics methods instance

您好我有通用 java类

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());

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

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

为什么Java允许(1)。

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

1 个答案:

答案 0 :(得分:1)

首先,方法声明中的Id会影响类级别的Id类型参数,因此Ref是泛型类的事实与此无关。如果只是将方法声明更改为

,则代码是等效的
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());(尽管它完全有效),因为

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