Java通用方法约束 - 从约束中排除类型以防止擦除问题? [英] Java generic method constraints - exclude type from constraint to prevent erasure problems?
问题描述
我试图基于类型约束重载一个方法。代码如下所示:
protected static< T extends ComponentTemplate> void addComponent(List< ComponentTemplate> factors,T component)
{
...
}
protected static< T extends ComponentTemplate
& ConditionalComponent> void addComponent(List< ComponentTemplate> factors,T conditionalComponent)
{
....
}
ComponentTemplate
是一个抽象类,并且 ConditionalComponent
是一个接口。这两种方法可以将组件添加到组件列表中。在组件实现 ConditionalComponent
的情况下,应该使用其他方法来确定是否应添加特定组件。当对象没有实现 ConditionalComponent
。
时会使用完全不同的方法。问题是这些方法具有相同的擦除(根据RAD,当然拒绝编译这个)。有没有办法定义第一个方法,使它排除 ComponentTemplate
AND ConditionalComponent
?我想象了这样的事情:
protected static< T extends ComponentTemplate
& !ConditionalComponent> void addComponent(List< ComponentTemplate> factors,T component)
{
...
}
但当然,这不起作用(这不是有效的语法)。是我试图做甚至可能的,还是有解决方法?
这是不允许的。为什么不呢?
当在Java中调用方法时,会使用具有最具体类型签名的方法。
在这个例子中:
接口A {...}
接口B {...}
class X extends A,B {...}
void f(X);
void f(A);
void f(B);
X x = ...
f(x); //调用f(X)
f((A)x); //调用f(A)
f((B)x); //调用f(B)
我们都知道如何转换以调用我们想要的正确方法。
但在例子中,
< T extends X> void g(T); // G1
g(x); //调用G1
我们可以调用 G1
,但无法在不进行重定向的情况下调用 G2
。
我们不能贬低为 A& B
,只限于 A
或 B
。
A& B
似乎没有很好地整合到类型系统中(大多数人甚至不知道它),因此Java不会将 A
看作是与 A& B
。
更多疯狂的例子:
接口A
接口B扩展A
< T扩展A& B个void f(T)
< T扩展B> void f(T)
这会编译,但你不能调用其中任何一个
B b = new B(){...}
f(B); //方法引用是不明确的。
I am trying to overload a method based on type constraints. The code looks something like this:
protected static <T extends ComponentTemplate> void addComponent(List<ComponentTemplate> factors, T component)
{
...
}
protected static <T extends ComponentTemplate
& ConditionalComponent> void addComponent(List<ComponentTemplate> factors, T conditionalComponent)
{
....
}
ComponentTemplate
is an abstract class, and ConditionalComponent
is an interface. These two methods can add a component to a list of components. In the case that the component implements ConditionalComponent
, there will be additional methods that should be used to determine if the specific component should be added. A completely different approach is used when the object does not implement ConditionalComponent
.
The problem is that these methods have the same erasure (according to RAD, which of course refuses to compile this). Is there a way to define the first method such that it excludes any objects that extends both ComponentTemplate
AND ConditionalComponent
? I imagined something like this:
protected static <T extends ComponentTemplate
& !ConditionalComponent> void addComponent(List<ComponentTemplate> factors, T component)
{
...
}
But of course, that doesn't work (it's not valid syntax). Is what I'm trying to do even possible, or is there a work-around?
This is not allowed. Why not?
When methods are called in Java, the method with the most specific type signiture is used.
In the example:
interface A {...}
interface B {...}
class X extends A, B {...}
void f(X);
void f(A);
void f(B);
X x = ...
f(x); // calls f(X)
f((A)x); // calls f(A)
f((B)x); // calls f(B)
We all know how to cast to call the correct method we want.
But in the example
<T extends X> void g(T); //G1
<T extends A & B> void g(T); //G2
g(x); // calls G1
We can call G1
, but there is no way to call G2
without redirection.
We cannot downcast to A & B
, only to either A
or B
.
The A & B
does not seem well intgrated into the type system (most people won't even know of it), therefore Java does not see A
as being a different type from A & B
when choosing which version of a method to dispatch to.
Futher examples of madness:
interface A
interface B extends A
<T extends A & B> void f(T)
<T extends B> void f(T)
This will compile, but you can't call either of them
B b = new B(){...}
f(B); // method reference is ambiguious.
这篇关于Java通用方法约束 - 从约束中排除类型以防止擦除问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!