0

我对参数化类型有一种奇怪的行为。我有一个扩展类 B 的类 A。A 有一个扩展类 Predicate 的内部类 A1。代码如下所示:

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

任何的想法?

4

2 回答 2

1

行为根本不受泛型的影响。它是编译时特性,泛型信息在编译后(实际上)丢失了。所以问题出在其他地方,IMO。

顺便说一句,你为什么不只介绍 Predicate getFilter() 并覆盖覆盖。会变得更具可读性。

于 2013-01-14T19:49:17.400 回答
0

问题在于 Java 泛型类型擦除。我使用的 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;
}

问候!

于 2013-01-15T02:26:37.020 回答