簡體   English   中英

了解Java中的泛型語法-將多個接口實現為參數的泛型類型

[英]Understanding generics syntax in java - generic types implementing multiple interfaces as parameters

我有一些接口(為完整起見,還提供了兩個虛擬類,因此您可以將代碼復制到自己的ide中)

public interface ItfA
{
  String getA();
}

public interface ItfB
{
  String getB();
}

public class MyClassAdapter
{
    public Object getValue(Object bean)
    {
        return null; // override to do something useful
    }
}

public class MyClass
{
    public MyClass(MyClassAdapter mca)
    {
        // do something useful with it
    }
}

而且我有一些使用這些函數作為參數的函數(看起來有些怪異,但這就是我必須使用它們的方式(我無法更改MyClassAdapter ))...

public <T extends ItfA> MyClass getMyClass(final Class<T> itf)
{
    return new MyClass(new MyClassAdapter()
        {
            @Override
            public Object getValue(Object bean)
            {
                return itf.cast(bean).getA();
            }
        }
    );
}

所以我只能在實現接口ItfA類中調用此getMyClass否則編譯器會抱怨。

或者,我可以不用命名泛型T來重寫此方法為...

public MyClass getMyClass2(final Class<? extends ItfA> itf)
{
    return new MyClass(new MyClassAdapter()
        {
            @Override
            public Object getValue(Object bean)
            {
                return itf.cast(bean).getA();
            }
        }
    );
}

在某些情況下,我需要將類用作實現多個接口的參數-這將起作用:

public <T extends ItfA & ItfB> MyClass getMyOtherClass(final Class<T> itf)
{
    return new MyClass(new MyClassAdapter()
        {
            @Override
            public Object getValue(Object bean)
            {
                return itf.cast(bean).getA() + itf.cast(bean).getB();
            }
        }
    );
}

但這不起作用

public MyClass getMyOtherClass2(final Class<? extends ItfA & ItfB> itf)
{
    return new MyClass(new MyClassAdapter()
        {
            @Override
            public Object getValue(Object bean)
            {
                return itf.cast(bean).getA() + itf.cast(bean).getB();
            }
        }
    );
}

我沒有得到這兩種通用參數之間的區別(在方法名稱之前使用<T extends ItfA>並在參數中使用Class<T>而不是在參數中使用Class<? extends ItfA> )-為什么兩者都做類型只能在一個接口上使用,為什么一個可以在兩個接口上使用,而另一個卻不能。

有什么提示嗎? 對我來說,第二個變種更具可讀性,所以我更願意這樣做,但我不希望它與多個接口一起使用...

TypeParameter不同, TypeArgument不能有多個界限,所以<? extends ItfA & ItfB> <? extends ItfA & ItfB>無效。

這是我對為什么會這樣的猜測。

我認為原因是TypeArgument需要特定才能有用。 例如,對於Class<T> ,方法cast返回T ,則您應該能夠聲明該類型的變量並將結果分配給它。

TypeArgument可以是:

  1. 類類別
  2. InterfaceType
  3. 的TypeVariable
  4. 數組類型
  5. 通配符

情況1-4沒問題,那里總是有一些特定的類型或類型變量。

對於通配符,我們有WildcardBounds,例如<? extends IntfA> <? extends IntfA>

如果只允許一個上限,那么您就有T特定值。 如果是Class<? extends IntfA> Class<? extends IntfA>你可以假設cast返回InfA

如果允許多於一個上限<? extends ItfA & ItfB> <? extends ItfA & ItfB>那么問題是,那么您可以將T用於什么? 由於通常情況下您沒有T任何特定類型,因此您能做的最好的事情是Object ,它不是很有用。

我認為這是語言作者沒有為通配符類型參數分配多個上限的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM