如果我有一个带有如下通用方法的接口:
public interface Thing {
void <T extends Comparable<? super T>> doSomething(List<T> objects);
}
我在某些地方需要那些丑陋的泛型类型规范,但大多数实现实际上并不需要它:
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) { ... }
}
据我所知,这应该是完全类型安全的,但是这种速记的变化是否有效?我确实理解编译器不允许覆盖非泛型方法,但这是用通配符替换类型参数的情况。我的猜测是实际上并不支持,因为编译器可以轻松支持
public class IDontCareAboutSortingThingx100 implements Thing {
@Override
public void <T> doSomething(List<T> objects) { ... }
}
即。覆盖较弱的界限,但似乎不允许这样做。无论如何,只是好奇,如果有人对这样的案件有一个神奇的咒语。
答案 0 :(得分:4)
不太确定你要去哪里,但是你不能将这些限制封装在一个单独的类中吗?
public class It<T extends Comparable<? super T>> {
public List<T> them;
}
public interface Thing {
void doSomething(It<String> them);
}
答案 1 :(得分:1)
基本上你要求的是逆变方法参数,例如:非通用示例如下所示:
interface I {
void m(String s);
}
class C implements I {
@Override
public void m(Object o) {}
}
void(Object)
是void(String)
的子签名,因为扩展转换始终可以。 Java没有这个。
对于泛型,可能覆盖泛型方法为非泛型:
class NotGeneric implements Thing {
@Override
public void doSomething(List rawList) {}
}
但你基本上不应该这样做。您将获得raw type warnings,您应该听取他们的意见。它可用于向后兼容。
如果是我,我会重复丑陋的通用签名,因为我不认为这一切都很难看。
你可以做的其他事情就像
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
必须是抽象类。)
当然,如果Thing
实际上是一个大型接口,这可能是不可行的。如果合适的话,你也可以用这种方式宣布Thing
。
答案 2 :(得分:0)
您可以将类型信息嵌入到类:
中public class IDontCareAboutSortingThingx100<T extends Comparable<? super T>> implements Thing<T> {
@Override
public void doSomething(List<T> objects) {
}
}