在Java中,如何获取作为泛型参数传递给函数的实体字段?

在Java中,如何获取作为泛型参数传递给函数的实体字段?,java,generics,java-8,generic-programming,Java,Generics,Java 8,Generic Programming,我有一个接收任何实体类的泛型方法。我的所有实体都有一个LocalDate类型的createDate字段。我想访问并获取泛型方法中的字段。方法是这样的 public static < T > List<Resource> printArray( List<T> entity) { for( T e : entity ) { LocalDate d = e.getCreateDate(); //Wrong } 公共静态列表打印数组

我有一个接收任何实体类的泛型方法。我的所有实体都有一个LocalDate类型的createDate字段。我想访问并获取泛型方法中的字段。方法是这样的

public static < T > List<Resource> printArray( List<T> entity) {
    for( T e : entity ) {
        LocalDate d = e.getCreateDate(); //Wrong
    }
公共静态列表打印数组(列表实体){
对于(T e:实体){
LocalDate d=e.getCreateDate();//错误
}
我不想检查泛型参数的实例并对其进行类型转换,因为有很多实体,我希望代码是最小的(因此是泛型函数)。
我如何才能做到这一点?

您可以使用抽象方法
getCreateDate()

假设您的所有实体都实现了此接口,则您的方法如下所示:

public static <T extends IDate> List<Resource> printArray(List<T> entity) {
    for(T e : entity ) {
        LocalDate d = e.getCreateDate();
    }
}
公共静态列表打印数组(列表实体){
对于(T e:实体){
LocalDate d=e.getCreateDate();
}
}
否则,您无法保证传递到此方法的实体具有方法
getCreateDate()


有一个反射解决方案是由

建议的,您可以使用抽象方法
getCreateDate()

假设您的所有实体都实现了此接口,则您的方法如下所示:

public static <T extends IDate> List<Resource> printArray(List<T> entity) {
    for(T e : entity ) {
        LocalDate d = e.getCreateDate();
    }
}
公共静态列表打印数组(列表实体){
对于(T e:实体){
LocalDate d=e.getCreateDate();
}
}
否则,您无法保证传递到此方法的实体具有方法
getCreateDate()


有一种反射解决方案是由

建议的。您可以使用反射来调用泛型类型上具有给定名称的方法

    for( T e : entity ) {
        try {
            Method method = e.getClass().getMethod("getCreateDate");
            method.invoke(e);
        }
        catch(Exception e1) {
            e1.printStackTrace();
        }                       
    }

可以使用反射调用泛型类型上具有给定名称的方法

    for( T e : entity ) {
        try {
            Method method = e.getClass().getMethod("getCreateDate");
            method.invoke(e);
        }
        catch(Exception e1) {
            e1.printStackTrace();
        }                       
    }

当实体类型没有公共超类型来声明
getCreateDate
方法,并且无法更改类型层次结构时,必须使用委派:

public static <T> List<Resource> printArray(
    List<? extends T> entities, Function<? super T, ? extends LocalDate> accessor) {

    for(T e: entities ) {
        LocalDate d = accessor.apply(e);
        // ...
    }
    // ...
}

其中
EntityType
指的是列表的特定元素类型。

当实体类型没有公共超类型来声明
getCreateDate
方法,并且无法更改类型层次结构时,必须使用委派:

public static <T> List<Resource> printArray(
    List<? extends T> entities, Function<? super T, ? extends LocalDate> accessor) {

    for(T e: entities ) {
        LocalDate d = accessor.apply(e);
        // ...
    }
    // ...
}

其中
EntityType
指的是列表中的特定元素类型。

您的实体都有一个公共父类吗?还是只有一个类型?没有公共父类。所有实体都有一个公共字段。@daveYou可以创建一个公共父类(比如
BaseClass
),保存此日期字段及其访问器。然后使用
。完成此操作后,您应该能够访问
e.getCreateDate()
。没有其他方法吗?我不想更改项目中的现有实体。@daveNo。如果您不想强制转换(而且不应该这样做)然后,您需要修改类以清晰地支持这一点。您可以使用反射来解决这一问题,但这进一步突出了您的设计中缺少的一些东西。您的实体都有一个公共父类吗?还是只有一种类型?没有公共父类。所有实体都有一个公共字段。@daveYou可以创建一个公共字段然后,父类(比如说
BaseClass
)保存此日期字段及其访问器。然后使用
。完成此操作后,您应该能够访问
e.getCreateDate()
。没有其他方法吗?我不想更改项目中的现有实体。@daveNo。如果您不想强制转换(也不应该这样做)然后,您需要修改您的类以清晰地支持这一点。您可以使用反射来解决它,但这进一步突出了您的设计中缺少的东西。还有其他方法吗?因为我不想更改项目中已经存在的实体。对于我的代码,我不想更改现有的实体实体。@Ruslan还有其他方法吗?因为我不想更改项目中已经存在的实体。对于我的代码,我不想更改现有的实体。@Ruslan