簡體   English   中英

Java語法:公共類Me擴展了功能<String,Integer,Character>

[英]Java syntax: public class Me extends Thing<String,Integer,Character>

免責聲明 :我是Java泛型和集合的新手。

背景 :我在這里這里都研究了Java泛型的基礎知識。 現在,我試圖了解它們如何應用於Hadoop的Mapperpublic static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable>

問題 :直到今天,我僅在類定義中看到占位符public class OrderedPair<K,V> implements Pair<K,V> ),而不是具體的類( public class Me extends Thing<String,Integer,Character> )。

問題 :總的來說,如果我有這個...

public class Me extends Thing<String,Integer,Character>

...“擴展Thing<String,Integer,Character> ”是什么意思? 看來我在“擴展” Thing,即Me子類繼承了Thing超類的方法。 那繼承與Thing<String,String,String>是否不同?

說明 :換句話說,擴展沒有泛型的類(例如, public class X extends Y )和有泛型( public class X extends Y<a,b,c> )之間的區別是什么?

通用類可以具有與之一起使用的不同類型(實例化它的對象時,可以選擇使用哪種類型)。 如果您擴展通用類並在其中放置具體類型,就像您在此處所做的那樣: public class Me extends Thing<String,Integer,Character> ,這意味着Me正在擴展Thing,但是Thing現在不再是通用的,因為它已經綁定到給定的類型。

以前,您可以將Thing實例化為:

Thing<String, Character, Integer> myThing = new Thing<>();

但我現在已受約束,您不能再為其選擇類型。

Me myMe = new Me();

您還可以使用實際的通用類型擴展Thing,因此您的Me類仍然是通用的。

public class <T, K, V> Me extends Thing<T, K, V>
...
// init with
Me<String, Character, Integer> myMe = new Me<>();

這樣,您可以在任何給定的通用類型下初始化Me,並將其傳遞給通用Thing。

您也可以部分完成。 因此,Thing的某些類型是固定的,在實例化Me時可以自由選擇。

public class <T> Me extends Thing<String, T, String>
...
// init with
Me<String> myMe = new Me<>();

擴展具有泛型類型的類時,可以選擇指定子類將在其下工作的類型。 例如, class MyList extends ArrayList<String>將具有ArrayList方法,但特定於字符串。

以同樣的方式,在擴展Mapper ,需要指定映射器將要處理的參數類型。 您可以通過提供Mapper聲明的類型參數來實現。

澄清:換句話說,在不使用泛型的情況下擴展類(例如,公共類X擴展Y)與在泛型中進行public class X extends Y<a,b,c>public class X extends Y<a,b,c> )之間有什么區別?

區別在於,在第二種情況(泛型類)中,如果要編譯良好,則必須遵守泛型類指定的類型的約束,否則應聲明原始子類。
通常,由通用類指定的類型由其方法使用。
因此正確定義它們很重要。
您主要有3種情況。

采取此通用類聲明,該聲明指定3個參數,並在myMethod()方法中使用它們:

public class Y <A extends AClass,B extends BClass, C extends CClass> {
    public void myMethod(A a, B b, C c){
         ...
    }
}

1)您的子類是原始類:

public class Z extends Y {
       ....
}

在這種情況下,它可以編譯正常但帶有警告。
您將失去泛型方法調用的好處。 編譯器將考慮具有此簽名的Z方法:

public void myMethod(Object a, Object b, Object c){
     ...
}

2)您的子類是通用的兼容子類:

public class Z extends Y<ASubClass,BSubClass,CSubClass> {
       ....
}

編譯器將考慮具有此簽名的Z方法:

public void myMethod(ASubClass a, BSubClass b, CSubClass c){
     ...
}

3)您的子類是泛型類,但不符合父類指定的參數,因此會出現編譯錯誤。

public class Z extends Y<BSubClass,ASubClass,CSubClass> {
       ....
}

如果超類型使用泛型,那么與任何泛型類型一樣,在沒有泛型參數的情況下引用它是使用原始類型的嚴重錯誤。 您必須為通用類型中的每個類型變量使用通用類型變量或具體類型。 例如,變量將像

Thing<String, Integer, Character> thing = new Thing<>();

自然不同於

Thing<String, String, String> thing = ...

因為它處理不同的類型!

繼承同樣適用。 在您的情況下,您將類型參數鎖定為具體類型。

public class SomeThing extends Thing<String, Integer, Character> { ...

鎖定SomeThing可以處理的類型,因此SomeThing實際上不是泛型類。

暫無
暫無

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

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