ps: 這里我不會(huì)詳細(xì)去記錄泛型的使用,只是我在學(xué)習(xí)中碰到的泛型使用的點(diǎn)
1. 泛型可以作為另一個(gè)泛型的參數(shù)注入
我有一個(gè)類: BasePersenter ,聲明需要傳入一個(gè)泛型參數(shù)
public abstract class BasePersenter<V extends IBaseView> {
...........
}
然后我們有另一個(gè)類: BaseActivity 款熬,需要使用 BasePersenter 這個(gè)類,來做為某個(gè)泛型的限定范圍
public abstract class BaseActivity<V extends IBaseView, P extends BasePersenter<V>> extends AppCompatActivity implements IBaseView {
...........
}
然后我們就可以看到首先聲明的 泛型 V 攘乒,作為參數(shù)傳入了 后面聲明的泛型 P : P extends BasePersenter<V>
2. 聲明的泛型參數(shù)可以暫時(shí)不設(shè)置這個(gè)泛型需要使用的泛型贤牛,而是有具體的繼承類來指定
先聲明一個(gè)類,需要傳入一個(gè)泛型類型
public abstract class BasePresenter<V>
在使用上面這個(gè)泛型時(shí)可以先指定泛型類型
public abstract class BaseActivity<P extends BasePresenter, B extends ViewDataBinding> extends DataBindingActivity<B>
由具體的繼承類來指定泛型類型
abstract class Presenter extends BasePresenter<AdviseContract.View>
最終 activity 的實(shí)現(xiàn)類的泛型使用
public class AdviseActivity extends BaseActivity<AdvisePresenter, ActivityFeedbackBinding>
3. 泛型可以通過繼承的方式则酝,一步步的縮小泛型的限定范圍
我們有一個(gè)頂層接口 : IBaseTest
public interface IBaseTest<D extends Object,A extends Object> {
...........
}
然后有一個(gè)類:BaseTest 殉簸,實(shí)現(xiàn)了這個(gè)接口,對(duì)其中的泛型做了限定
public class BaseTest<D extends String, A extends String> implements IBaseTest<D, A> {
...........
}
4. 注意泛型的寫法沽讹,是繼續(xù)向下傳遞還是在這里聲明具體類型
- 向下傳遞的寫法般卑,接著上面的 例子:
public class BaseTest<D extends String, A extends String> implements IBaseTest<D, A> {
...........
}
- 不向下傳遞了,直接指定具體類型了
public class BaseTest implements IBaseTest<String爽雄,String> {
...........
}
- 寫在類名下的泛型是屬性聲明的蝠检,是需要子類來指定類型的
- 寫在該類繼承的基類類名或是實(shí)現(xiàn)的接口接口名下的都是屬于指定具體的泛型類型了,注意這種寫法挚瘟,我們?cè)賹懸粋€(gè)子類繼承該類叹谁,那么這個(gè)子類就無法再指定父類的泛型類型了,因?yàn)樯冻烁牵驗(yàn)楦割惗紱]聲明泛型焰檩,你怎么去指定
5. 注意單獨(dú)的泛型方法寫法的不同
/**
* 泛型方法
* Created by zhongtian465 on 2017-10-12.
*/
public class GenericMethod {
/**
* 泛型方法
* @param clazz 用來創(chuàng)建泛型對(duì)象 、Class<T>:指明泛型T的具體類型
* @param <T> 聲明此方法為泛型方法侧漓,且有個(gè)類型T
* @return T 返回類型是T
* @throws IllegalAccessException
* @throws InstantiationException
*/
public <T> T getObject(Class<T> clazz) throws IllegalAccessException, InstantiationException {
T object= clazz.newInstance();
return object;
}
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
GenericMethod genericMethod = new GenericMethod();
User user = (User) genericMethod.getObject(Class.forName("com.zt.study.java.generic.User"));
System.out.println(user);
}
}
泛型方法在返回值前面加上一個(gè) " <T> " 來表示這是一個(gè)泛型方法锅尘,這里這個(gè)泛型 T 和類聲明的泛型不是一回事,不沖突布蔗,各用各的
優(yōu)秀資料:
絕對(duì)是代碼封裝藤违,泛型使用的經(jīng)典案例,寫的太好了纵揍,非常深度顿乒,我現(xiàn)在寫的還差的遠(yuǎn)呢
泛型學(xué)習(xí)的基礎(chǔ)文章:
-
Java泛型(一)
- java'是偽泛型,我們?cè)诖a寫的是泛型泽谨,但是在編譯時(shí)會(huì)擦除所有的泛型標(biāo)記璧榄,用具體類型來替換泛型類型特漩,這是在編譯器在編譯時(shí)干的事
- 泛型不能用在竟然唉的方法和參數(shù)中,因?yàn)殪o態(tài)是屬于類型加載器的骨杂,不是數(shù)據(jù)一個(gè)具體類型對(duì)象的涂身,我們不在一個(gè)具體的對(duì)象中聲明具體的類型,泛型怎么知道要轉(zhuǎn)換成什么類型呢搓蚪。除非你把這個(gè)靜態(tài)方法聲明為靜態(tài)泛型方法
-
Java泛型(二)
- 具體師范了泛型 - 類蛤售,方法,泛型方法妒潭,對(duì)泛型的使用
- 明確了泛型的通配符的使用 List<? extends Number> / List<? super Integer>
- 明確了泛型逆變與協(xié)變應(yīng)該怎么寫悴能,這個(gè)很重要的,用的 list 做的例子
-
16.泛型介紹及泛型類雳灾、泛型方法漠酿、泛型接口
- 沒說理論,用簡單的代碼說明泛型使用的谎亩。