Java泛型:这足够安全吗?

Java泛型:这足够安全吗?,java,generics,Java,Generics,考虑以下代码段: public interface FieldEnum { public String getEnumName(); } 以下代码安全吗 public class EnumConverter { public static <T extends FieldEnum> T convert(String enumName, T[] enumValues) { for (T enumValue : enumValues) {

考虑以下代码段:

public interface FieldEnum {
    public String getEnumName();
}


以下代码安全吗

public class EnumConverter {
    public static <T extends FieldEnum> T convert(String enumName, T[] enumValues) {
        for (T enumValue : enumValues) {
            if (enumName.equals(enumValue.getEnumName())) {
                return enumValue;
            }
        }
        throw new IllegalStateException("orm.enums.EnumConverter.convert: No suitable enum has been found. enumName = " + enumName + " fieldEnums = " + enumValues);
    }
}
公共类枚举转换器{
公共静态T转换(字符串枚举名,T[]枚举值){
for(T枚举值:枚举值){
if(enumName.equals(enumValue.getEnumName())){
返回枚举值;
}
}
抛出新的IllegalStateException(“orm.enums.EnumConverter.convert:未找到合适的枚举。enumName=“+enumName+”fieldEnums=“+enumValues”);
}
}
或者使用这个会有什么好处?(注意添加了
类clazz
参数)

公共类枚举转换器{
公共静态T转换(字符串enumName,T[]enumValues,类clazz){
for(T枚举值:枚举值){
if(enumName.equals(enumValue.getEnumName())){
返回枚举值;
}
}
抛出新的IllegalStateException(“orm.enums.EnumConverter.convert:未找到合适的枚举。enumName=“+enumName+”fieldEnums=“+enumValues”);
}
}
然后通过EnumConverter.convert调用它(rs.getString(9),InvoiceStatus.values(),InvoiceStatus.class)当然可以


注意。

泛型使用第一个
T
type参数的类类型。添加新的
不会增加任何安全性。事实上,您现在需要知道要将哪个类放入参数列表中,这可能会很麻烦。

泛型使用第一个
T
类型参数的类类型。添加新的
不会增加任何安全性。事实上,您现在需要知道要将哪个类放入参数列表中,这可能会很麻烦。

不需要额外的参数-编译器将能够从传递的数组中确定类型T,因此不需要显式地将类作为参数。

不需要额外的参数-编译器将能够从传递的数组中确定类型T,因此不需要显式地将类作为参数。

一个简单的答案是忘记EnumConverter,而是使用
InvoiceStatus.valueOf(rs.getString(9))

一个简单的答案是忘记EnumConverter,而是使用
InvoiceStatus.valueOf(rs.getString(9))

我建议使用以下方法:

public enum InvoiceStatus implements FieldEnum {
    UNCHECKED("unchecked"),
    ERROR("error"),
    OK("ok");

    private static final Map<String, InvoiceStatus> invoiceStatusMap = new HashMap<>(values().length);

    static{
        for (InvoiceStatus  invoiceStatus : values()) {
            invoiceStatusMap.put(invoiceStatus.enumName, invoiceStatus);
        }
    }    
    private final String enumName;

    private InvoiceStatus(final String enumName) {
        this.enumName = enumName;
    }

    @Override
    public String getEnumName() {
        return enumName;
    }

    public static InvoiceStatus getInvoiceStatus(String enumName){
        if (invoiceStatusMap.contains(enumName)){
           return invoiceStatusMap.get(enumName);
        } else {
            throw new IllegalArgumentException("No suitable enum has been found. enumName = " + enumName + " fieldEnums = " + enumValues);
        }
    }
}
public enum InvoiceStatus实现FieldEnum{
未经检查(“未经检查”),
错误(“错误”),
OK(“OK”);
私有静态最终映射invoiceStatusMap=新HashMap(values().length);
静止的{
对于(InvoiceStatus InvoiceStatus:values()){
invoiceStatusMap.put(invoiceStatus.enumName,invoiceStatus);
}
}    
私有最终字符串枚举名;
私有发票状态(最终字符串enumName){
this.enumName=enumName;
}
@凌驾
公共字符串getEnumName(){
返回枚举名;
}
公共静态InvoiceStatus getInvoiceStatus(字符串enumName){
if(invoiceStatusMap.contains(enumName)){
返回invoiceStatusMap.get(enumName);
}否则{
抛出新的IllegalArgumentException(“未找到合适的枚举。enumName=“+enumName+”fieldEnums=“+enumValues”);
}
}
}

我建议使用以下方法:

public enum InvoiceStatus implements FieldEnum {
    UNCHECKED("unchecked"),
    ERROR("error"),
    OK("ok");

    private static final Map<String, InvoiceStatus> invoiceStatusMap = new HashMap<>(values().length);

    static{
        for (InvoiceStatus  invoiceStatus : values()) {
            invoiceStatusMap.put(invoiceStatus.enumName, invoiceStatus);
        }
    }    
    private final String enumName;

    private InvoiceStatus(final String enumName) {
        this.enumName = enumName;
    }

    @Override
    public String getEnumName() {
        return enumName;
    }

    public static InvoiceStatus getInvoiceStatus(String enumName){
        if (invoiceStatusMap.contains(enumName)){
           return invoiceStatusMap.get(enumName);
        } else {
            throw new IllegalArgumentException("No suitable enum has been found. enumName = " + enumName + " fieldEnums = " + enumValues);
        }
    }
}
public enum InvoiceStatus实现FieldEnum{
未经检查(“未经检查”),
错误(“错误”),
OK(“OK”);
私有静态最终映射invoiceStatusMap=新HashMap(values().length);
静止的{
对于(InvoiceStatus InvoiceStatus:values()){
invoiceStatusMap.put(invoiceStatus.enumName,invoiceStatus);
}
}    
私有最终字符串枚举名;
私有发票状态(最终字符串enumName){
this.enumName=enumName;
}
@凌驾
公共字符串getEnumName(){
返回枚举名;
}
公共静态InvoiceStatus getInvoiceStatus(字符串enumName){
if(invoiceStatusMap.contains(enumName)){
返回invoiceStatusMap.get(enumName);
}否则{
抛出新的IllegalArgumentException(“未找到合适的枚举。enumName=“+enumName+”fieldEnums=“+enumValues”);
}
}
}

足够安全做什么?因为你没有使用
clazz
参数,我不认为第二个解决方案会更好。InvoiceStatus.valueOf(myString)有什么问题?如果你想让别人检查你的代码,可能会更好。@Keppil“Safe”在泛型中有很好的定义,它不是基于意见的。不幸的是,没有链接。对什么足够安全?因为你没有使用
clazz
参数,我不认为第二个解决方案会更好。InvoiceStatus.valueOf(myString)有什么问题?如果你想让别人检查你的代码,可能会更好。@Keppil“Safe”在泛型中定义得很好,它不是基于意见的东西。不幸的是,没有链接。这并没有考虑我想将它与
.getEnumName()
进行比较的事实,现在它只从一个枚举中获取正常的
.name()
,这不是我正在搜索的100%行为,但是我可以研究重写
name()的可能性
。这并没有考虑我想将它与
.getEnumName()
进行比较的事实,现在它只是从一个枚举中获取正常的
.name()
,这不是我正在搜索的100%行为,但是我可以研究重写
name()
的可能性。
public class EnumConverter {
    public static <T extends FieldEnum> T convert(String enumName, T[] enumValues, Class<T> clazz) {
        for (T enumValue : enumValues) {
            if (enumName.equals(enumValue.getEnumName())) {
                return enumValue;
            }
        }
        throw new IllegalStateException("orm.enums.EnumConverter.convert: No suitable enum has been found. enumName = " + enumName + " fieldEnums = " + enumValues);
    }
}
public enum InvoiceStatus implements FieldEnum {
    UNCHECKED("unchecked"),
    ERROR("error"),
    OK("ok");

    private static final Map<String, InvoiceStatus> invoiceStatusMap = new HashMap<>(values().length);

    static{
        for (InvoiceStatus  invoiceStatus : values()) {
            invoiceStatusMap.put(invoiceStatus.enumName, invoiceStatus);
        }
    }    
    private final String enumName;

    private InvoiceStatus(final String enumName) {
        this.enumName = enumName;
    }

    @Override
    public String getEnumName() {
        return enumName;
    }

    public static InvoiceStatus getInvoiceStatus(String enumName){
        if (invoiceStatusMap.contains(enumName)){
           return invoiceStatusMap.get(enumName);
        } else {
            throw new IllegalArgumentException("No suitable enum has been found. enumName = " + enumName + " fieldEnums = " + enumValues);
        }
    }
}