繁体   English   中英

稍后在Java代码中定义实例通用类型

[英]Define instance generic type later on in code in Java

我有这样的课:

public class Foo<T>
{
//What ever inside
}

后来我想做这样的事情:

public class MyClass
{
    Foo foo;
    public MyClass(int x)
    {
       if(x==1)
       {
           foo = new Foo<Integer>();
           //EDIT1
           handleFooWhenItIsInteger();
           //EDIT1
       }
       else
       {
           foo = new Foo<String>();
           //EDIT1
           handleFooWhenItIsString();
           //EDIT1
       }
}

假设我在函数'handleFooWhenItIsInteger()'中进行了一些整数运算,并在另一个函数中进行了一些字符串处理。

像上面那样定义'foo'可以吗?

但是,这将编译原始类型的使用,例如

Foo foo;

不建议使用通用类型Foo<T> 仅出于遗留原因才支持原始类型,即与引入泛型的Java 5之前编写的代码兼容。

为了描述任何通用Foo,您应该编写Foo<?>来描述任何通用类型的Foo实例。 然后,编译器将检查您是否稍后在代码中对这些实例调用任何非类型安全的方法,例如在您的情况下,该实例可以引用Foo<Integer>Foo<String> 由于使用了通配符类型 Foo<?> ,您可以使用相同的变量来引用这两个变量,但是您不能再对所引用实例的实际通用类型进行假设。

从技术上讲,使用FooFoo<?>之间没有太大区别。 但是,使用前者,编译器将针对使用原始类型生成警告。 编译器无法确定您没有忘记添加泛型类型参数,而只是偶然使用了原始类型。 这就是为什么如果需要通配符引用,应该花几个字符总添加<?>

好的 但是foo是通用的,在构造函数之外使用时,您不知道它是什么类型。

这将起作用,但会产生警告,因为Foo foo的声明未参数化。 然后,您将负责确保所有Foo交互在整个代码中都是一致的。 否则,您可能会遇到一些ClassCastException

像上面那样定义'foo'可以吗?

不,这是原始类型

Foo foo;

由于原始类型不是通用的。 相当于

Foo<Object> foo;

您应该具有Foo的类型。 所以像

Foo<Integer> foo;

或者可能

public class MyClass<T> {
  Foo<T> foo;

正如其他人已经说过的那样:它将在编译时带有一些警告,但最有可能的行为与

public class MyClass
{
    Foo foo;
    public MyClass(int x)
    {
       foo = new Foo();
    }
}

这是为什么?

  • Java泛型仅启用编译时检查,在运行时,您使用泛型提供的所有信息都会丢失。
  • 编译器仅知道声明的内容-因此,使用标识符foo它仅知道它是Foo但没有有关其泛型类型的信息
  • 在使用new Foo<String>()时,在赋给foo后调用构造函数时,可能会有所不同,编译器将不再对此有所了解。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM