在接口级别java中使用通用通配符

时间:2017-08-22 01:58:48

标签: java generics wildcard

这与java通用外卡有关。我需要了解这是如何发生的,需要解决方案。

Ex:我有一个名称为Processer的接口。

import my_lib
# Use these commands in the same cell.
%load_ext autoreload
%autoreload 2

我想把P作为通配符。但是在定义时不允许使用通配符(?)。

当我实现此接口并让IDE生成实现的方法时,它会生成如下。

public interface Processer<X> {
    <P> void process(P parent, X result);
}

我想修改此实现。

public class FirstProcesser implements Processer<String> {
    @Override
    public <P> void process(P parent, String result) {

    }
}

但它给出了编译错误,FirstProcesser应该是抽象的或实现所有抽象方法。

我需要知道为什么会发生这种情况并找到解决方案。

1 个答案:

答案 0 :(得分:0)

重写

您无法覆盖方法 (通用与否) 使用较窄的参数类型。 如果可以的话,编译器就不可能判断是否有任何给定的方法调用 (将来时) 合法的。

一个没有任何泛型的例子,它将以完全相同的错误失败:

public class X {
    public void f(Object o) {
    }
}

class Y extends X {
    @Override
    public void f(String s) {
    }
}

编译失败的原因是:

X.java:8: error: method does not override or implement a method from a supertype
    @Override
    ^
1 error

如果它是合法的,那么就不可能可靠地编译甚至非常简单的方法,如:

public static void f(X x) {
    x.f(5);
}

如果x是实际的X对象,那么该代码可以正常运行,但如果xY子类型,则会失败,因为{{1} }不是5。 这就是为什么不允许String的上述定义覆盖Y.f

通过将X.f更改为仅接受FirstProcesser个对象,您会遇到同样的问题。

责任链

chain of responsibility pattern on Wikipedia 看起来不像你想要建立的那样。 我可以想到你可能要做的两件事......

1。 如果User参数应该是链中的前一个处理程序,那么它应该是parent类型:

Processer<X>

2。 如果public interface Processer<X> { void process(Processer<X> parent, X result); } class StringProcesser implements Processer<String> { @Override public void process(Processer<String> parent, String result) { } } 的类型是决策过程的一部分,则每个处理程序应存储它可以处理的parent个对象的集合。 然后,Class方法应该查看该集合中是否有process

部分定义可能类似于:

parent.getClass()

请注意,泛型类型参数public interface Processer<X> { void process(Class<?> parent, X result); } class StringProcesser implements Processer<String> { private Set<Class<?>> classes = new HashSet<Class<?>>(); public StringProcesser(final Iterable<Class<?>> classes) { for (final Class<?> c : classes) { this.classes.add(c); } } @Override public void process(Class<?> parent, String result) { if (this.classes.contains(parent)) { System.err.println("Handling..."); System.out.println(result); return; } System.err.println( "Can't handle. Try next Processer." ); // ... } } 和通配符<X>出现的位置取决于您要执行的操作。

PS:“Processer”应拼写为“Processor”。