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