簡體   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