Java泛型:这样安全吗?

时间:2013-07-23 12:31:30

标签: java generics

请考虑以下代码段:

public interface FieldEnum {
    public String getEnumName();
}

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

    private final String enumName;

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

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

private InvoiceBean(final Integer invoiceId, final Integer businessPartnerId, final String invoiceNumber, final Date invoiceDate, final BigDecimal priceExclVAT, final BigDecimal VAT, final BigDecimal priceInclVAT, final BigDecimal paymentDiscount, final InvoiceStatus status) {
    this.invoiceId = invoiceId;
    this.businessPartnerId = businessPartnerId;
    this.invoiceNumber = invoiceNumber;
    this.invoiceDate = invoiceDate;
    this.priceExclVAT = priceExclVAT;
    this.VAT = VAT;
    this.priceInclVAT = priceInclVAT;
    this.paymentDiscount = paymentDiscount;
    this.status = status;
}

public InvoiceBean(final ResultSet rs) throws SQLException {
    this(rs.getInt(1), rs.getInt(2), rs.getString(3), rs.getDate(4), rs.getBigDecimal(5), rs.getBigDecimal(6), rs.getBigDecimal(7), rs.getBigDecimal(8), EnumConverter.convert(rs.getString(9), InvoiceStatus.values()));
}

以下代码是否安全?

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

或者使用它会有什么好处吗? (注意添加Class<T> clazz参数)

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

然后通过EnumConverter.convert(rs.getString(9), InvoiceStatus.values(), InvoiceStatus.class)调用它。

问候。

4 个答案:

答案 0 :(得分:8)

直截了当的回答是忘记EnumConverter而是使用InvoiceStatus.valueOf(rs.getString(9));

答案 1 :(得分:3)

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

我建议使用类似的东西:

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