繁体   English   中英

如何在泛型类上调用通配符方法?

[英]How to call a wildcarded method on a generic class?

我有一个泛型类,其中类型变量用于方法的参数。 当我使用有界通配符从SetMapList检索泛型类的实例时,如何调用此方法?

泛型类的超级类:

//Verifier.java
import java.lang.annotation.Annotation;

public interface Verifier<A extends Annotation> {
    // A verifier needs the annotation to extract verification information.
    public boolean verifyValue(Object value, A annotation);
}

具体实现:

//MinMaxVerifyer.java
public class MinMaxVerifyer implements Verifier<MinMax> {
    @Override
    public boolean verifyValue(Object value, MinMax annotation) {
        if (!(value instanceof Number)) return false;

        long l = ((Number)value).longValue();
        long min = annotation.min();
        long max = annotation.max();

        return l >= min && l <= max;
    }
}

示例中使用的注释:

//MinMax.java
import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.METHOD)
@Inherited
public @interface MinMax {
    long min() default Long.MIN_VALUE;
    long max() default Long.MAX_VALUE;
}

包含违规呼叫的类:

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.*;

public class ParameterVerifier {
    private static final Map<String, Verifier<? extends Annotation>> verifyers
        = new HashMap<>();

    static {
        verifyers.put("MinMax", new MinMaxVerifyer());
        // verifyers.put(Range.class, new RangeVerifier());
        // verifyers.put(NotNull.class, new NotNullVerifier());
    }

    public void validate(Method method, Object value) {
        for (Annotation annotation : method.getAnnotations()) {
            String name = annotation.getClass().getSimpleName();
            Verifier<? extends Annotation> verifier = verifyers.get(name);

            if (verifier != null) {
                boolean valid = verifier.verifyValue(value, annotation);
                // ^ The method
                // verifyValue(Object, capture#5-of ? extends Annotation)
                // in the type Verifier<capture#5-of ? extends Annotation>
                // is not  applicable for the arguments (Object, Annotation)
            }
        }
    }
}

我正在尝试使其工作,以便用户可以添加自己的注释/验证者对,并且应该使用注释子类对验证者进行参数化。 我不在乎是否必须在ParameterVerifier (不在公共API的验证程序中)。 我知道如何使用一些额外的逻辑来添加对类型安全的对,为清楚起见,在此省略。

相关: 类型为Validator <capture#2-of的方法validate(capture#2-of扩展对象) extend Object>不适用于参数(字符串),并且Java通用/通配符类型不匹配都建议限制为特定的Verifier子类型或从Verifier中删除类型变量。 我正在寻找更优雅的解决方案。 (考虑MinMaxVerifyer.java是不可变的,只能在其他版本上使用。)

我不知道为什么我以前没有找到这个。 我以为我会尝试使用泛型的所有组合。 这样可以编译并完美地完成工作。

  • 从检索到的元素中删除通配符(而不是通用),然后进行强制转换并告诉编译器它是安全的。
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.*;

public class ParameterVerifier {

    private static final Map<String, Verifier<? extends Annotation>> verifiers
        = new HashMap<>();

    static {
        verifiers.put(Range.class.getSimpleName(), new RangeVerifyer());
    }

    public void validate(Method method, Object value) {
        for (Annotation annotation : method.getAnnotations()) {
            String name = annotation.getClass().getSimpleName();
            @SuppressWarnings("unchecked")
            Verifier<Annotation> verifier =
                (Verifier<Annotation>)verifiers.get(name);
            if (verifier != null) {
                boolean valid = verifier.verify(value, annotation);
            }
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM