Java通用类型在这种情况下不起作用

时间:2018-09-21 00:37:11

标签: java generics java-10

此类显示信息:

// display line numbers from a file 
display(getLineNumber(myFile));

// display users from DB
display(getUsersName(myDBRepository));

等...

我想创建一个通用接口,以便可以外部化显示信息的代码。

然后我可以做类似的事情:

myInformationElements.stream().forEach(e -> display(e.getValue());

这是我到目前为止(无法正常工作)的内容:

public interface InformationElement {
    public <T> String getValue (T param);
}


public class NbFileLineInformationElement implements InformationElement{
    @Override
    public <File> String getValue(File param) {
          return *same code as in getLineNumber(myFile)*;
    }
}

public class UserInformationElement implements InformationElement{
      @Override
      public <UserRepository> String getValue(UserRepository param) {
         return *same code as in getUsersName(myDBRepository)*;
   }
}
  1. 这里我的通用类型不起作用:文件未重新调整为java.io.File(与我的jpa存储库相同)在这里我做错了什么?
  2. 这是满足我需求的最佳实践吗?

1 个答案:

答案 0 :(得分:3)

  1. 您已经定义了类型参数FileUserRepository,它们遮盖了类名FileUserRepository。这是与现有类相同的命名类型参数的惊喜之一。类型参数不能表示类,也没有边界,因此编译器只能假定它们具有Object方法。

  2. 这不是最佳实践。在实现泛型方法时,这些方法必须保持泛型,并且至少在范围方面是敞开的。为了能够稍后限制类型参数的含义,请在类/接口上对其进行定义,然后让子类使用类型参数提供对该特定实现应具有的含义。

这里最好的解决方案是将InformationElement的类型参数移到类中,并在子类中提供类型参数。这些方法不再通用,但它们确实使用在接口/类上定义的类型参数。

interface InformationElement<T> {
    public String getValue (T param);
}

class NbFileLineInformationElement implements InformationElement<File>{
    @Override
    public String getValue(File param) {
          return /*same code as in getLineNumber(myFile)*/;
    }
}

class UserInformationElement implements InformationElement<UserRepository>{
      @Override
      public String getValue(UserRepository param) {
         return /*same code as in getUsersName(myDBRepository)*/;
   }
}