使用 javac 编译器编译泛型
compiling generics with javac compiler
我在使用 javac 时遇到以下错误(与 java 泛型有关)
:inconvertible types
[ERROR] required: (...)
[ERROR] found: (...)
代码在 eclipse 中编译正常(因为它没有使用 javac )。
我在以下代码中遇到错误:
public <T extends Comparable<T>> TRange<T> valueToRange(T val, List<T> rangeValues) {
List<T> vals = rangeValues;
if (vals == null) {
vals = (List<T>) (this.values != null ? this.values : this.defaultValues);
}
return valueToRange(val, vals, this.range);
}
其中值和 defaultValues
属于 Serializable
的 List
类型
和
public static <T extends Enum<T> & Unit> Class<T> getEnumClass(String unitValueClassName) {
unitValueClassName = normalizeEnumClassName(unitValueClassName);
if (unitValueClassName.equals(DENSITY_CLS)) {
return (Class<T>) DensityUnit.class;
}
if (unitValueClassName.equals(LENGTH_CLS)) {
return (Class<T>) LengthUnit.class;
}
if (unitValueClassName.equals(LENGTH_OPTIONAL_CLS)) {
return (Class<T>) LengthUnit.class;
}
if (unitValueClassName.equals(VOLUME_CLS)) {
return (Class<T>) VolumeUnit.class;
}
if (unitValueClassName.equals(WEIGHT_CLS)) {
return (Class<T>) WeightUnit.class;
}
if (unitValueClassName.equals(TIME_CLS)) {
return (Class<T>) TimeUnit.class;
}
throw new IllegalArgumentException("Please add the enum class to UnitValueView.getEnumClass(String) : " + unitValueClassName);
}
我们可以用另一种保持相同功能但通过 javac 编译器的方式重写它们吗?
第一个代码片段实际上是危险的:您试图将 List<Serializable>
转换为 List<T>
,其中 T
是 Comparable<T>
。您最终可能会在 Comparable
列表中得到 non-comparable 项,这可能会在运行时突然产生 ClassCastException
。不知道 three-argument valueToRange
的实现,我不能说如何正确解决这个问题。但是如果你还是觉得这样还可以,只是想让这段代码可以编译,可以再加一个cast:
public <T extends Comparable<T>> TRange<T> valueToRange(T val, List<T> rangeValues) {
List<T> vals = rangeValues;
if (vals == null) {
vals = (List<T>) (List<?>) (this.values != null ? this.values : this.defaultValues);
}
return valueToRange(val, vals, this.range);
}
对于第二个例子,你可以做类似的事情:
public static <T extends Enum<T> & Unit> Class<T> getEnumClass(String unitValueClassName) {
unitValueClassName = normalizeEnumClassName(unitValueClassName);
Class<?> clazz;
if (unitValueClassName.equals(DENSITY_CLS)) {
clazz = DensityUnit.class;
} else if (unitValueClassName.equals(LENGTH_CLS)) {
clazz = LengthUnit.class;
} else if (unitValueClassName.equals(LENGTH_OPTIONAL_CLS)) {
clazz = LengthUnit.class;
} else if (unitValueClassName.equals(VOLUME_CLS)) {
clazz = VolumeUnit.class;
} else if (unitValueClassName.equals(WEIGHT_CLS)) {
clazz = WeightUnit.class;
} else if (unitValueClassName.equals(TIME_CLS)) {
clazz = TimeUnit.class;
} else {
throw new IllegalArgumentException("Please add the enum class to UnitValueView.getEnumClass(String) : " + unitValueClassName);
}
return (Class<T>) clazz;
}
我在使用 javac 时遇到以下错误(与 java 泛型有关)
:inconvertible types
[ERROR] required: (...)
[ERROR] found: (...)
代码在 eclipse 中编译正常(因为它没有使用 javac )。
我在以下代码中遇到错误:
public <T extends Comparable<T>> TRange<T> valueToRange(T val, List<T> rangeValues) {
List<T> vals = rangeValues;
if (vals == null) {
vals = (List<T>) (this.values != null ? this.values : this.defaultValues);
}
return valueToRange(val, vals, this.range);
}
其中值和 defaultValues
属于 Serializable
List
类型
和
public static <T extends Enum<T> & Unit> Class<T> getEnumClass(String unitValueClassName) {
unitValueClassName = normalizeEnumClassName(unitValueClassName);
if (unitValueClassName.equals(DENSITY_CLS)) {
return (Class<T>) DensityUnit.class;
}
if (unitValueClassName.equals(LENGTH_CLS)) {
return (Class<T>) LengthUnit.class;
}
if (unitValueClassName.equals(LENGTH_OPTIONAL_CLS)) {
return (Class<T>) LengthUnit.class;
}
if (unitValueClassName.equals(VOLUME_CLS)) {
return (Class<T>) VolumeUnit.class;
}
if (unitValueClassName.equals(WEIGHT_CLS)) {
return (Class<T>) WeightUnit.class;
}
if (unitValueClassName.equals(TIME_CLS)) {
return (Class<T>) TimeUnit.class;
}
throw new IllegalArgumentException("Please add the enum class to UnitValueView.getEnumClass(String) : " + unitValueClassName);
}
我们可以用另一种保持相同功能但通过 javac 编译器的方式重写它们吗?
第一个代码片段实际上是危险的:您试图将 List<Serializable>
转换为 List<T>
,其中 T
是 Comparable<T>
。您最终可能会在 Comparable
列表中得到 non-comparable 项,这可能会在运行时突然产生 ClassCastException
。不知道 three-argument valueToRange
的实现,我不能说如何正确解决这个问题。但是如果你还是觉得这样还可以,只是想让这段代码可以编译,可以再加一个cast:
public <T extends Comparable<T>> TRange<T> valueToRange(T val, List<T> rangeValues) {
List<T> vals = rangeValues;
if (vals == null) {
vals = (List<T>) (List<?>) (this.values != null ? this.values : this.defaultValues);
}
return valueToRange(val, vals, this.range);
}
对于第二个例子,你可以做类似的事情:
public static <T extends Enum<T> & Unit> Class<T> getEnumClass(String unitValueClassName) {
unitValueClassName = normalizeEnumClassName(unitValueClassName);
Class<?> clazz;
if (unitValueClassName.equals(DENSITY_CLS)) {
clazz = DensityUnit.class;
} else if (unitValueClassName.equals(LENGTH_CLS)) {
clazz = LengthUnit.class;
} else if (unitValueClassName.equals(LENGTH_OPTIONAL_CLS)) {
clazz = LengthUnit.class;
} else if (unitValueClassName.equals(VOLUME_CLS)) {
clazz = VolumeUnit.class;
} else if (unitValueClassName.equals(WEIGHT_CLS)) {
clazz = WeightUnit.class;
} else if (unitValueClassName.equals(TIME_CLS)) {
clazz = TimeUnit.class;
} else {
throw new IllegalArgumentException("Please add the enum class to UnitValueView.getEnumClass(String) : " + unitValueClassName);
}
return (Class<T>) clazz;
}