繁体   English   中英

Java在匿名类定义中引用Enum类型

[英]Java referencing Enum type in anonymous class definition

我正在尝试定义以下匿名Google Guava Function实例:

Function<E extends Enum<E>, String> ENUM_TO_STRING = new Function<E extends Enum<E>, String>() {
    @Override
    public String apply(E enumValue) {
        String result = null;
        if (enumValue != null) {
            result = enumValue.toString();
        }
        return result;
    }
};

这个想法是一个简单的转换函数实例,带有apply方法,如果不为null,则对任何枚举值调用toString;如果值为null,则返回null。

不幸的是,编译器抱怨通用引用E扩展了Enum。 我知道此表达式可以在非匿名上下文中使用,例如:

public static <E extends Enum<E>> String enumToString(E enumValue) {
    String result = null;
    if (enumValue != null) {
        result = enumValue.toString();
    }
    return result;      
}

第一个匿名类定义不正确。 第二个非匿名方法定义是可以的。

反正有使用Enums定义匿名类的方法吗?

谢谢

正如Sotirios所指出的 ,泛型类型参数只能为类或方法声明,而不能为字段声明。 实际上,声明E可能是不必要的Function<Enum<?>, String>就可以了:

Function<Enum<?>, String> ENUM_TO_STRING = new Function<Enum<?>, String>() {
    @Override
    public String apply(Enum<?> enumValue) {
        if (enumValue != null) {
            return enumValue.toString();
        }
        return null;
    }
};

按照这种思路, toString是由Object而不是Enum声明的,因此常规的Function<Object, String>更有意义:

Function<Object, String> NULLABLE_TO_STRING = new Function<Object, String>() {
    @Override
    public String apply(Object obj) {
        if (obj != null) {
            return obj.toString();
        }
        return null;
    }
};

通常,最好将实现细节隐藏在工厂方法后面,以使将来的更改更容易,例如:

private static final Function<Object, String> NULLABLE_TO_STRING = ...

public static Function<Object, String> nullableToString() {
    return NULLABLE_TO_STRING;
}

请注意,仍在返回Function<Object, String> 只要您的API使用PECS (例如,接受Function<? super Foo, ? extends Bar> ),这就可以了,但是我们也可以通过使方法通用来进一步提供特定的输入类型:

private static final Function<Object, String> NULLABLE_TO_STRING = ...

public static <T> Function<T, String> nullableToString() {
    @SuppressWarnings("unchecked") // safe contravariant cast
    final Function<T, String> withNarrowedType =
            (Function<T, String>)(Function<?, String>)NULLABLE_TO_STRING;
    return withNarrowedType;
}

请注意,这使用相同的Function实例,并且未经检查的强制转换会缩小其输入类型。 NULLABLE_TO_STRING是安全的,因为NULLABLE_TO_STRING可以接受任何对象并且是无状态的。 此模式在Joshua Bloch的有效Java项目27“喜欢的通用方法”中得到了证明。

您不能在任何地方使用通用类型变量。 您必须处于可以声明它们且可以访问它们的上下文中。

在第二个示例中,它们在方法签名中声明。

在第一个示例中,似乎没有在任何地方声明E 换句话说,您不能将类型变量声明为变量声明的一部分。 如果代码所在的方法或类声明了类型变量E本身,则可以执行尝试的操作。

您可能根本不需要泛型,因为您实际上并没有使用类型信息,而且无论如何它都会在运行时丢失。 首先从老式的函数apply(Enum enumValue)开始。 如果您确实不想抑制警告并需要类型检查,则可以从那里进一步进行调查。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM