类型的通用方法

时间:2015-05-14 10:42:13

标签: java generics

我有以下界面:

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

6 个答案:

答案 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;
        }
   }