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

稍后在Java代码中定义实例泛型类型,java,generics,definition,Java,Generics,Definition,我有一门课是这样的: public class Foo<T> { //What ever inside } public class MyClass { Foo foo; public MyClass(int x) { if(x==1) { foo = new Foo<Integer>(); //EDIT1 handleFooWhenItIsIntege

我有一门课是这样的:

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
       }
}
公共类Foo
{
//里面有什么
}
后来我想做这样的事情:

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
       }
}
公共类MyClass
{
富富,;
公共MyClass(int x)
{
如果(x==1)
{
foo=新的foo();
//编辑1
开始使用时的手柄门();
//编辑1
}
其他的
{
foo=新的foo();
//编辑1
HandleFooowheintissString();
//编辑1
}
}
假设我在函数“handlefootwheinitisinteger()”中做了一些整数运算,并在另一个函数中处理了一些字符串


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

可以。但是
foo
是泛型的,当您在构造函数外部使用时,您无法知道它是什么类型。

这会起作用,但会生成警告,因为
foo
的声明没有参数化。然后,您将负责确保所有
foo
交互都是c否则,您可能会遇到一些
类异常

这将编译,但是,使用

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

为了描述任何泛型Foo,您应该编写
Foo
,它描述任何泛型类型的
Foo
实例。然后,编译器将检查您在代码的后面没有对这些实例调用任何非类型安全的方法,例如,在您的示例中,该实例可以引用
Foo
>或
Foo
。由于使用了通配符类型
Foo
,您可以使用相同的变量引用这两个变量,但不能再对引用实例的实际泛型类型进行假设

从技术上讲,使用
Foo
Foo
没有太大区别。但是,使用前者,编译器将生成使用原始类型的警告。编译器无法确定您是否忘记添加泛型类型参数,而只是意外地使用了原始类型。这就是为什么您应该花费很少的时间如果需要通配符引用,则始终添加字符

像上面这样定义“foo”可以吗

不,是一个,这个

由于原始类型的原因,它不是泛型的。它等效于

Foo<Object> foo;
Foo-Foo;
你应该有Foo的类型,比如

Foo<Integer> foo;
Foo-Foo;
或许

public class MyClass<T> {
  Foo<T> foo;
公共类MyClass{
富富,;

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

public class MyClass
{
    Foo foo;
    public MyClass(int x)
    {
       foo = new Foo();
    }
}
为什么呢

  • Java泛型只支持编译时检查,在运行时,您使用泛型提供的所有信息都将丢失
  • 编译器只知道声明了什么-因此当使用标识符
    foo
    时,它只知道它是
    foo
    ,但没有关于其泛型类型的信息
  • 当使用
    new Foo()
    时,如果在
    Foo
    赋值后调用构造函数,编译器将不再知道它,那么使用
    new Foo()
    可能会有点不同

我知道这里的情况。让我编辑我的代码[EDIT1]更准确。谢谢。