Java泛型:重写泛型方法,通配符速记? [英] Java Generics: Overriding generic methods, wildcard shorthand?

查看:110
本文介绍了Java泛型:重写泛型方法,通配符速记?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我的接口具有如下通用方法:

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泛型:重写泛型方法,通配符速记?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆