下面的 SCCE 显示了实现接口 Marker 的 2 个类(B 和 C)。对于每个实现 Marker 的类,都有一个相应的类实现通用 Handler 接口(B_Handler、C_Handler)。映射用于将 Pair.second 的类类型与其关联的处理程序相关联。代码按预期执行;但是,我收到一个编译时警告:
警告:[unchecked] unchecked cast Handler h1 = (Handler) (dispatch.get(p1.second.getClass())); 要求:找到的处理程序:处理程序,其中 CAP#1 是一个新的类型变量:CAP#1 从 ? 扩展标记
除了@SuppressWarnings(value = "unchecked") 之外,解决这个问题的最干净的方法是什么?
package genericpair;
import java.util.HashMap;
import java.util.Map;
import javax.swing.SwingUtilities;
public class GenericPair
{
public class A
{
}
public interface Marker
{
}
public class B implements Marker
{
}
public class C implements Marker
{
}
public Pair<A, Marker> getTarget()
{
A a = new A();
C c = new C();
return new Pair<>(a, c);
}
public interface Handler<T extends Marker>
{
void handle(Pair<A, T> target);
}
public class B_Handler implements Handler<B>
{
@Override
public void handle(Pair<A, B> target)
{
System.out.println("B");
}
}
public class C_Handler implements Handler<C>
{
@Override
public void handle(Pair<A, C> target)
{
System.out.println("C");
}
}
public class Pair<F, S>
{
public final F first;
public final S second;
public Pair(F first, S second)
{
this.first = first;
this.second = second;
}
}
private void executeSCCE()
{
// register a handler for each Marker type
Map<Class, Handler<? extends Marker>> dispatch = new HashMap<>();
dispatch.put(B.class, new B_Handler());
dispatch.put(C.class, new C_Handler());
// get a target (e.g., Pair<A,C>)
Pair<A, Marker> p1 = getTarget();
// select handler based on the class type of the second parameter
Handler<Marker> h1 = (Handler<Marker>) (dispatch.get(p1.second.getClass()));
h1.handle(p1);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(() -> new GenericPair().executeSCCE());
}
}
Run Code Online (Sandbox Code Playgroud)
Consider the following example:
List<? extends List> test1 = new ArrayList<>();
List<List> test2 = (List<List>) test1;
Run Code Online (Sandbox Code Playgroud)
Here we get the warning:
warning: [unchecked] unchecked cast
List<List> test2 = (List<List>) test1;
^
required: List<List>
found: List<CAP#1>
where CAP#1 is a fresh type-variable:
CAP#1 extends List from capture of ? extends List
Run Code Online (Sandbox Code Playgroud)
发生这种情况是因为无法确保List<List> will的通用约束匹配List<? extends List>。想象一下,我们将此示例重写为以下内容:
List<? extends List> test1 = new ArrayList<ArrayList>();
List<List> test2 = (List<List>) test1;
test1.add(new LinkedList<>());//ERROR no suitable method found for add(LinkedList<Object>)
test2.add(new LinkedList<>());//Will work fine!!
Run Code Online (Sandbox Code Playgroud)
这里更明显的是初始合约被破坏了。定义为包含的列表ArrayList现在包含一个LinkedList. 这是不安全的,也是您收到此警告的原因。所以没有办法从Handler<? extends Marker>toHandler<Marker>安全地投射。
| 归档时间: |
|
| 查看次数: |
859 次 |
| 最近记录: |