参数化类问题

时间:2013-01-14 18:24:41

标签: java generics inheritance

我在参数化类型中遇到了奇怪的行为。 我有一个扩展B类的A类.A有一个内部类A1,它扩展了Predicate类。 代码如下所示:

public abstract class A<T> extends B<T> {
    public T uniqueResult (String param, Object value) {
        A1 filter = new A1();
        filter.setParam(param);
        filter.setValue(value);
        return container.query(filter).next();
    }
    public class A1 extends Predicate<T> {
        public boolean match (T bean) {
            Object result = BeanUtils.getPropertyValue(bean, fieldName);
            return result == null ? null : result.equals(value);
        }  
    }
}

最后,D类扩展了A并使用了uniqueResult方法:

public class D extends A<MyVO> {
    public MyVO findById (BigDecimal id) {
        return uniqueResult("id", id);
    }
}

问题是匹配方法(在A1内)接收BigDecimal而不是MyVO。 如果我在D中覆盖uniqueResult方法,它可以正常工作,但我不知道为什么会发生这种情况。

覆盖的uniqueResult看起来像这样:

public MyVO uniqueResult (final String fieldName, final Object value) {
    return container().query(
        new Predicate<MyVO>() {
            private static final long   serialVersionUID    = 1L;
            public boolean match(MyVO bean) {
                Object result = BeanUtils.getPropertyValue(bean, fieldName);
                return result == null ? null : result.equals(value);
            }
        }
    ).next();
}

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

行为不会受到泛型的影响。它是编译时功能,编译后(有效)丢失了泛型信息。所以问题出在其他地方,IMO。

顺便说一下为什么不介绍Predicate getFilter()并覆盖覆盖。会更具可读性。

答案 1 :(得分:0)

问题出在Java Generics类型擦除上。 我正在使用的API(包含类Predicate)在创建像Predicate这样的参数化谓词时会出现问题。幸运的是,它提供了一个构造函数,它接收要作为参数匹配的具体类。它不优雅,但它有效。

代码是这样的:

A:

中的方法uniqueResult
protected T uniqueResult (final String fieldName, final Object value) {
    return container().query(
        new Predicate<T>(getPredicateClass()) {
            private static final long   serialVersionUID    = 1L;
            public boolean match(T bean) {
                Object result = BeanUtils.getPropertyValue(bean, fieldName);
                return result == null ? null : result.equals(value);
            }
        }
    ).next();
}

已添加

protected abstract Class<T> getPredicateClass();

最后在D:

protected Class<MyVO> getPredicateClass() {
    return MyVO.class;
}

问候!