为什么Java中不允许类中的隐式泛型? [英] Why are implicit generics in classes not allowed in Java?

查看:71
本文介绍了为什么Java中不允许类中的隐式泛型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图理解为什么Java不允许像在通用方法中那样在通用类中使用隐式类型.

I am trying to understand why Java does not allow using implicit types in generic classes as it does in generic methods.

我已经在网上搜寻了有关此问题的答案,但是还没有遇到为什么 Java不支持以下内容的原因:

I have scoured the webs for answers on this, but have yet to come across a reason as to why something like the following is not supported in Java:

// This will not compile:
public <T> interface ElementPicker<L extends List<T>> { ... }

// This on the other hand will
public interface ElementPicker<T, L extends List<T>> { ... }

因此,我们必须在类通用参数中明确提及类型T.当然,这意味着我们现在必须始终编写:

And so we must explicitly mention the type T in the class generic arguments. This of course means that we must now always write:

ElementPicker<Integer, List<Integer>>
// instead of just:
ElementPicker<List<Integer>>

这会导致我的代码不断出现头痛,在这种情况下,我试图明智地使用泛型来平衡代码,同时使我的类型可读且简短.

This leads to a constant head-ache in my code where I am attempting to balance using generics wisely, while making my types readable and short.

不幸的是,在我当前的项目中,我正在处理一堆嵌套的泛型类型,它们的类型实参冒泡到顶部,因此我的超长类必须包含所有泛型类型数据.

Unfortunately, in my current project I am dealing with a bunch of nested generic types, and their type arguments are bubbling to the top so that I have very long top-level classes that must include all generic type data.

要查看这如何成为问题,请考虑:

To see how this can become a problem consider:

interface ScalarValue<T extends Number> {
  T toNumber();
}

interface ScalarAdder<T, U extends ScalarValue<T>> {
  T add(U v1, U v2);
}

class ScalarAccumulator<T, U extends ScalarValue<T>, 
                           A extends ScalarAdder<T, U>> {
  ...
}

// Assuming we have these implementations:
class RationalValue implements ScalarValue<Float> { .. }
class RationalAdder implements ScalarAdder<Float, RationalValue> { .. }

// A typical type could look like this monster:
ScalarAccumulator<Float, RationalValue, RationalAdder>

// Whereas an implicit declaration like this:
public <T extends Number, 
        U extends ScalarValue<T>,
        A extends ScalarAdder<T, U>
class ScalarAccumulator<A> { ... }

// ... would allow us to simply write
ScalarAccumulator<RationalAdder>
// ...as all other types can be inferred.

同样,这是一个例子,但是我在工作中经常遇到这类事情.我还没有找到为什么这不可能的原因.方法就可以了(从单个值及其类推断类型).

Again this is an example, but I encounter these kinds of things quite often in my work. And I have yet to find a reason for why this is not possible. Methods can this just fine (infer types from a single value and its class).

那么,为什么Java可以在方法中而不是在类中支持它呢?我想不出一个例子,在这个例子中,一个类不明确地包含类型是一个问题.但是我可能缺少一些东西.

So why can Java support this in methods but not in classes? I cannot think of an example where it would be a problem for a class to not explicitly include the type. But I am probably missing something.

如果有人对解决这种情况有任何好的建议,我也将不胜感激.

If anybody has any good tips on work-arounds to deal with such situations in general, I would also appreciate it.

推荐答案

在Java 10中,您可以使用var跳过类型声明.这是一种将其与类型推断结合在一起的方式(有点怪异),因此您可以在不声明所有嵌套类型的情况下创建实例:

In Java 10 you can use var to skip type declarations. Here's a (somewhat hacky) way to combine that with type inference so you can create an instance without declaring all the nested types:

static <T, U extends ScalarValue<T>, A extends ScalarAdder<T, U>> ScalarAccumulator<T, U, A> create(Class<A> adderClass) {
    return new ScalarAccumulator<>();
}

static void test() {
    var a = create(RationalAdder.class);
}

这篇关于为什么Java中不允许类中的隐式泛型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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