我有以下界面:
public interface Caster{
public boolean tryCast(Object value);
}
及其实施:
public class IntegerCaster{
public boolean tryCast(Object value){
try{
Integer.class.cast(value);
return true;
} catch (ClassCastException e){
return false;
}
}
}
public class DateCaster{
public boolean tryCast(Object value){
try{
Date.class.cast(value);
return true;
} catch (ClassCastException e){
return false;
}
}
}
是否可以将此类实现设为通用的?我们无法使用类型参数来声明Caster,因为我们无法按如下方式实现它:
public interface Caster<T>{
public boolean tryCast(Object value);
}
public class CasterImpl<T> implements Caster<T>{
public boolean tryCast(Object value){
try{
T.class.cast(value); //fail
return true;
} catch (ClassCastException e){
return false;
}
}
}
答案 0 :(得分:4)
您必须在通用Class
中注入<{em> T
CasterImpl
参数化的值public class CasterImpl<T> implements Caster<T> {
private Clazz<T> clazz;
public CasterImpl(Class<T> clazz) {
this.clazz = clazz;
}
public boolean tryCast(Object value){
try{
clazz.cast(value);
return true;
} catch (ClassCastException e){
return false;
}
}
}
。
这样的事情:
Caster
作为旁注:我没有看到FindWindow
界面为Generic的原因,因为您不在界面中使用type-parameter。
答案 1 :(得分:4)
使用标准Class.isInstance
方法可以在没有界面的情况下完成。如果您仍想实现此界面,请使用
public Caster getCaster(final Class<?> clazz) {
return new Caster() {
public boolean tryCast(Object value) {
return clazz.isInstance(value);
}
};
}
在Java 8中更简单:
public Caster getCaster(final Class<?> clazz) {
return clazz::isInstance;
}
答案 2 :(得分:3)
Java中的泛型由 erasure 实现。 Java为所有T
生成单字节码。
所以这个:
return T.class.cast(value);
会 - 如果允许的话 - 基本上成为
return Object.class.cast(value);
无论您指定哪个T
。如果要检查特定类,则需要Class<T>
对象。
someclass.isInstance(obj)
。目前,您重新发明 Class<T>
API 。
答案 3 :(得分:1)
当然,只需存储T
的类,以便稍后在构造函数中使用:
public interface Caster<T>{
public boolean tryCast(Object value);
}
public class CasterImpl<T> implements Caster<T>{
private Class<? extends T> cls;
public CasterImpl(Class<? extends T> cl) {
this.cls = cl;
}
public boolean tryCast(Object value){
try{
cls.cast(value); //fail
return true;
} catch (ClassCastException e){
return false;
}
}
}
答案 4 :(得分:1)
泛型类型的实例不存储其泛型类型参数。
您可以将该类存储为kocko,或者您可以通过这种方式将泛型类型参数存储在新类型中:
public abstract class CasterImpl<T> implements Caster<T>{
public boolean tryCast(Object value){
try{
getValueClass().cast(value);
return true;
} catch (ClassCastException e){
return false;
}
}
@SuppressWarnings("unchecked")
public Class<T> getValueClass() {
Class<? extends CasterImpl<T>> c = (Class<? extends CasterImpl<T>>) this.getClass();
ParameterizedType x = (ParameterizedType) c.getGenericSuperclass();
return (Class<T>) x.getActualTypeArguments()[0];
}
}
这只适用于这样的子类,它将类型存储在自己的类型定义中:
public class CasterIntegerImpl extends CasterImpl<Integer> {
// No need to implement anything
}
测试:
System.out.println(new CasterIntegerImpl().tryCast(1)); // true
System.out.println(new CasterIntegerImpl().tryCast("")); // false
答案 5 :(得分:0)
试试这个,使用T而不是Object
public interface Caster<T>{
public boolean tryCast(T value);
}
public class CasterImpl<T> implements Caster<T>{
private Class<? extends T> cls;
public CasterImpl(Class<? extends T> cl) {
this.cls = cl;
}
public boolean tryCast(T value){
try{
cls.cast(value); //fail
return true;
} catch (ClassCastException e){
return false;
}
}