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 内の) match メソッドが MyVO ではなく BigDecimal を受け取ることです。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 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;
}

よろしく!

于 2013-01-15T02:26:37.020 に答える