问题描述
如果我的接口具有如下通用方法:
If I have an interface with a generic method like the following:
public interface Thing {
void <T extends Comparable<? super T>> doSomething(List<T> objects);
}
在某些地方,我需要那种难看的通用typespec,但是大多数实现实际上并不需要它:
I need that ugly generic typespec in some places, but most implementations don't actually need it:
public class ICareAboutSortingThing implements Thing {
@Override
public void <T extends Comparable<? super T>> doSomething(List<T> objects) { ... }
}
public class IDontCareAboutSortingThingx100 implements Thing {
@Override
public void <T extends Comparable<? super T>> doSomething(List<T> objects) { ... }
}
我想写的是这样的:
public class IDontCareAboutSortingThingx100 implements Thing {
@Override
public void <?> doSomething(List<?> objects) { ... }
}
据我所知,这应该是完全类型安全的,但是这种速记形式是否可以适用?我确实知道编译器不允许使用非泛型方法进行覆盖,但这是用通配符替换类型参数的情况.我的猜测是实际上不支持此功能,因为编译器可以同样轻松地支持
This should be fully typesafe as far as I understand, but is there any variation of this kind of shorthand that would work? I do understand that the compiler doesn't allow overriding with non-generic methods, but this is a case of replacing type arguments with wildcards. My guess is that this isn't actually supported because the compiler could just as easily support
public class IDontCareAboutSortingThingx100 implements Thing {
@Override
public void <T> doSomething(List<T> objects) { ... }
}
即以较弱的边界覆盖,但这似乎是不允许的.无论如何,只是好奇是否有人对这种情况有魔咒.
i.e. overriding with weaker bounds, but that doesn't seem to be allowed. Anyhow, just curious if anyone has a magic incantation for cases like this.
推荐答案
本质上,您要求的是变量方法参数,例如一个非通用示例如下:
Essentially what you're asking for is contravariant method parameters, e.g. a non-generic example looks like:
interface I {
void m(String s);
}
class C implements I {
@Override
public void m(Object o) {}
}
void(Object)
是void(String)
的子签名,因为加宽转换始终可以. Java没有这个.
void(Object)
is a subsignature of void(String)
because the widening conversion is always OK. Java doesn't have this.
对于泛型,您可以将泛型方法重写为非泛型:
For generics, you may override a generic method to be non-generic:
class NotGeneric implements Thing {
@Override
public void doSomething(List rawList) {}
}
但是您基本上不应该这样做.您将收到原始类型警告你应该听他们的可以向后兼容.
But you basically shouldn't do it. You will get raw type warnings and you should listen to them. It's available for backwards compatibility.
如果是我,我会重复丑陋的通用签名,因为我认为这不是那么丑陋.
If it were me, I would just repeat the ugly generic signature because I don't think it's all that ugly.
您可能会做的其他事情
interface NonGenericThing extends Thing {
@Override
default <T extends Comparable<? super T>>
void doSomething(List<T> list) {
doSomethingImpl(list);
}
void doSomethingImpl(List<?> list);
}
然后您改为实现NonGenericThing
并覆盖doSomethingImpl
. (在Java 8之前,NonGenericThing
必须是抽象类.)
And then you implement NonGenericThing
instead and override doSomethingImpl
. (Prior to Java 8, NonGenericThing
must be an abstract class.)
当然,如果Thing
实际上是一个大接口,那可能不可行.如果合适的话,您也可以以这种方式声明Thing
.
Of course that might not be feasible if Thing
is actually a large interface. You could also declare Thing
this way to begin with, if it's appropriate.
这篇关于Java泛型:重写泛型方法,通配符速记?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!