最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java泛型基本知識及通用方法

 更新時間:2019年04月02日 10:26:11   作者:眺望小寒山  
這篇文章主要介紹了java泛型基礎(chǔ)知識及通用方法,從以下幾個方面介紹一下java的泛型: 基礎(chǔ), 泛型關(guān)鍵字, 泛型方法, 泛型類和接口,感興趣的可以了解一下

泛型的基本使用

泛型是Java SE 1.5的新特性, 泛型的本質(zhì)是參數(shù)化類型, 也就是說所操作的數(shù)據(jù)類型被指定為一個參數(shù). 這種參數(shù)類型可以用在類、接口和方法的創(chuàng)建中, 分別稱為泛型類、泛型接口、泛型方法.  Java語言引入泛型的好處是安全簡單.

今天就從以下幾個方面介紹一下java的泛型: 基礎(chǔ), 泛型關(guān)鍵字, 泛型方法, 泛型類和接口.

基礎(chǔ):

  通過集合的泛型了解泛型的基本使用

public void testBasis(){
 List<String> list = new ArrayList<String>();
// new ArrayList<int>();
 }
 
 //這是最基本的泛型使用, 就不多說了, 不過要注意的是泛型只能是引用數(shù)據(jù)類型, 不能是基本類型, 而且泛型只在編譯期有效, 在編譯后的class文件中是不存在泛型信息的

 注意: 泛型只在編譯期有效, 在編譯后的class文件中是不存在泛型信息的

泛型關(guān)鍵字:

  通配符?表示任意引用類型, extends關(guān)鍵字表示子類及其本身, super關(guān)鍵字是表示父類及其本身. 通過一個例子看一下, 解釋說明都在例子中

public void testKeyWord() throws Exception {
 //實例化參數(shù)類型必須指明具體類型
 List<?> list = new ArrayList<String>();
 //由于list中類型不明確, 所以不能進行添加操作
// list.add("sk");
 
 //通配符?表示任意引用類型
 List<List<?>> list1 = new ArrayList<List<?>>();
 //list1的參數(shù)化類型是一個List, 而這個List也是一個參數(shù)化類型, 它的類型是任意類型, 所以list1可以添加任意List類型對象
 list1.add(new ArrayList<Object>());
 list1.add(new ArrayList<String>());
 
 //實例化list2時指明了類型參數(shù)List, 只不過這個List是一個泛型類型
 //從這里可以看到關(guān)鍵字extends的用法, 其實就是繼承, 如下這里的list2中的參數(shù)化類型List(在這里記為paramList)的參數(shù)化類型是繼承自Number的
 //所以在list2在添加的時候只能添加參數(shù)化類型為Number及其子類的paramList
 List<Integer> l1 = new ArrayList<Integer>();
 List<Number> l2 = new ArrayList<Number>();
 List<Object> l3 = new ArrayList<Object>();
 List<List<? extends Number>> list2 = new ArrayList<List<? extends Number>>();
 list2.add(l1);
 list2.add(l2);
// list2.add(l3); //這里使用了extends關(guān)鍵字, 所以不能添加Number的父類
 
 //相信大家也猜到了, 既然extends關(guān)鍵字表示子類及其本身, 那么super關(guān)鍵字是表示父類及其本身, 是的, 沒錯
 //和上面的不一樣了, l1不能添加, 因為Integer是Number的子類, 并不是Number的父類
 List<List<? super Number>> list3 = new ArrayList<List<? super Number>>();
// list3.add(l1); //這里使用了super關(guān)鍵字, 所以不能添加Number的子類
 list3.add(l2);
 list3.add(l3);
 }

泛型方法:

  java中任何類型必須先定義才能使用, 泛型也是如此. 既然要使用泛型作為參數(shù), 所以要先定義, 泛型的定義在訪問修飾符和返回類型之間, 注意不要掉了尖括號

//無返回值有參的方法, 參數(shù)為泛型
 public <T> void show(T t){
 System.out.println("t-=-=" + t);
 }
 
 //有返回值的有參方法, 只有一個參數(shù)化類型, 這里定義泛型的方式和上面一樣, 也是先定義后使用, 只不過這里的返回類型是泛型
 public <T> T get(T t){
 return t;
 }
 
 //有返回值的有參方法, 有多個參數(shù)化類型, 這里以兩個為例
 public <T, K> K get(T t, K k){
 return k;
 }
 
 @Test
 public void testGeneric() throws Exception {
 show(3);
 show("generic");
 System.out.println("----------------");
 
 System.out.println("我返回Integer類型-" + get(4));
 System.out.println("我返回String類型-" + get("returnGeneric"));
 System.out.println("------------------");
 
 System.out.println("我返回String類型-" + get(1, "a"));
 System.out.println("我返回Integer類型-" + get("b", 2));
 }

  本來想寫無參的泛型方法, 可是寫著寫著感覺那樣沒有什么意義, 不知道各位有什么見解.

泛型類和接口:

  寫泛型類的時候只需要在類名后面加上泛型即可, 就像這樣

public class GenericClass<T> {
 public T get(T t){
  return t;
 }
 
 public void scr(T t){
  System.out.println(t);
 }

 public void show(){
  GenericClass<Integer> gc = new GenericClass<Integer>();
//  GenericClass<T> gc1 = new GenericClass<T>();
  gc.get(3);
  gc.scr(5);
  //下面2個會報錯
//  gc1.get(3);
//  gc1.scr(5);
 }
}

   從上面的例子中可以看到, 參數(shù)化類型是在創(chuàng)建對象的時候具體化的, 那么除此之外, 還可以再什么時候具體化參數(shù)化類型呢?

  如果是在繼承或?qū)崿F(xiàn)中, 可以在子類或?qū)崿F(xiàn)類中確定具體類型

使用java泛型設(shè)計通用方法

泛型是Java SE 1.5的新特性, 泛型的本質(zhì)是參數(shù)化類型, 也就是說所操作的數(shù)據(jù)類型被指定為一個參數(shù). 因此我們可以利用泛型和反射來設(shè)計一些通用方法. 現(xiàn)在有2張表, 一張user表和一張student表.

user:

student:

  如果要根據(jù)id查詢數(shù)據(jù), 你會怎么做呢?寫2個方法分別查詢user和student?其實這時候我們就可以使用泛型和反射寫一個通用的方法.

  user的實體類:

private Integer id;
 private String username;
 private String password;
 private String hobby;
 //getXxx方法和setXxx方法

  student實體類:

 private Integer id;
 private String name;
 private Integer age;
 //getXxx方法和setXxx方法

  BaseDao接口:

public interface BaseDao<T> {
 //根據(jù)id查詢的方法
 T findById(Integer id);
}

  BaseDaoImpl類, 實現(xiàn)了BaseDao接口, 通用方法就在這里面完成:

//設(shè)置為抽象的, 不讓他實例化, 讓其子類實例化就行了
//通過泛型設(shè)計通用方法的關(guān)鍵就是利用反射拿到泛型的具體類型
public abstract class BaseDaoImpl<T> implements BaseDao<T> {
 private String tableName;  //表名
 private Class<T> actualType;//真實類型

 /**
 * findById(Integer id)這個方法被子類繼承了, 假設(shè)我們在UserDaoImpl中操作, 此時參數(shù)化類型T為User
 * 下面的講解都假設(shè)是在UserDaoImpl中進行的
 */
 //把公共部分可以放到構(gòu)造方法中
 @SuppressWarnings("unchecked")
 public BaseDaoImpl() {
 //返回類型是Type 是 Java 編程語言中所有類型的公共高級接口. 它們包括原始類型、參數(shù)化類型、數(shù)組類型、類型變量和基本類型. 
 //Type的已知子接口: ParameterizedType 表示參數(shù)化類型, 如 Collection<String>. 
 //getClass()得到UserDaoImpl的Class, 得到Class一般有3中方式: getClass(), 類名.class, Class.forName()
 Type type = getClass().getGenericSuperclass();//獲取UserDaoImpl<User>的參數(shù)化類型的父類BaseDaoImpl<User>
 //由于我們得到的是一個參數(shù)化類型, 所以轉(zhuǎn)成ParameterizedType, 因為需要使用里面的方法
 ParameterizedType pt = (ParameterizedType) type;//強轉(zhuǎn)
 Type[] actualTypeArr = pt.getActualTypeArguments();//獲取真實參數(shù)類型數(shù)組[User.class], 可以調(diào)試看到這里的值
 actualType = (Class<T>) actualTypeArr[0];//數(shù)組只有一個元素
 tableName = actualType.getSimpleName();
 }
 
 @Override
 public T findById(Integer id) {
 String sql = "select * from " + tableName + " where id = ?";
 try {
 return QRUtils.getQueryRunner().query(sql, new BeanHandler<T>(actualType), id);
 } catch (SQLException e) {
 e.printStackTrace();
 }
 return null;
 }
}

  連接數(shù)據(jù)庫操作是用的c3p0和dbutils, 有關(guān)這方面的內(nèi)容可以參看我以前的隨筆.     

  UserDao接口, 繼承BaseDao接口:

public interface UserDao<T> extends BaseDao<T> {
}

  UserDaoImpl類, 實現(xiàn)UserDao接口, 繼承BaseDaoImpl類, 可以看到里面什么方法也沒有:

public class UserDaoImpl extends BaseDaoImpl<User> implements UserDao<User> {
}

  StudentDao接口, 繼承BaseDao接口:

public interface StudentDao<T> extends BaseDao<T> {
}

  StudentDaoImpl類, 實現(xiàn)StudentDao接口, 繼承BaseDaoImpl類, 也可以看到里面什么方法也沒有:

public class StudentDaoImpl extends BaseDaoImpl<Student> implements StudentDao<Student> {
}

  從以上dao可以看到, 我是在繼承BaseDaoImpl類時把泛型具體化了.

測試:

@Test
  public void testGeneric() throws Exception {
  UserDao<User> userDao = new UserDaoImpl();
  System.out.println(userDao.findById(1));
  
  System.out.println("-------------------");
  StudentDao<Student> studentDao = new StudentDaoImpl();
  System.out.println(studentDao.findById(1));
 }

  看一下測試的結(jié)果: 同一個方法把2張表中的數(shù)據(jù)都查出來了

  

相關(guān)文章

  • Spring Cloud重試機制與各組件的重試總結(jié)

    Spring Cloud重試機制與各組件的重試總結(jié)

    這篇文章主要給大家介紹了關(guān)于Spring Cloud中重試機制與各組件的重試的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。
    2017-11-11
  • 使用Spring的攔截器監(jiān)測每個Controller或方法的執(zhí)行時長

    使用Spring的攔截器監(jiān)測每個Controller或方法的執(zhí)行時長

    這篇文章主要介紹了使用Spring的攔截器監(jiān)測每個Controller或方法的執(zhí)行時長,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Liquibase結(jié)合SpringBoot使用實現(xiàn)數(shù)據(jù)庫管理功能

    Liquibase結(jié)合SpringBoot使用實現(xiàn)數(shù)據(jù)庫管理功能

    Liquibase 是一個強大的數(shù)據(jù)庫管理工具,它幫助你通過自動化管理數(shù)據(jù)庫的變更、版本控制、和回滾,簡化了開發(fā)中的數(shù)據(jù)庫遷移工作,這篇文章主要介紹了Liquibase結(jié)合SpringBoot使用實現(xiàn)數(shù)據(jù)庫管理,需要的朋友可以參考下
    2024-12-12
  • Java線程中synchronized的用法與原理解析

    Java線程中synchronized的用法與原理解析

    這篇文章主要介紹了Java線程中synchronized的用法與原理解析,只要有線程,就會有并發(fā)的現(xiàn)象,也同時會產(chǎn)生數(shù)據(jù)不一致,那么對于需要使用同一個數(shù)據(jù)的兩個線程,就會產(chǎn)生沖突,那么就引出了鎖的概念,本篇會針對性的說下synchronized這個關(guān)鍵字,需要的朋友可以參考下
    2024-01-01
  • 關(guān)于MyBatis通用Mapper@Table注解使用的注意點

    關(guān)于MyBatis通用Mapper@Table注解使用的注意點

    這篇文章主要介紹了關(guān)于MyBatis通用Mapper@Table注解使用的注意點,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 基于SpringBoot+vue實現(xiàn)前后端數(shù)據(jù)加解密

    基于SpringBoot+vue實現(xiàn)前后端數(shù)據(jù)加解密

    這篇文章主要給大家介紹了基于SpringBoot+vue實現(xiàn)前后端數(shù)據(jù)加解密,文中有詳細的示例代碼,具有一定的參考價值,感興趣的小伙伴可以自己動手試一試
    2023-08-08
  • Java數(shù)據(jù)結(jié)構(gòu)與算法學習之雙向鏈表

    Java數(shù)據(jù)結(jié)構(gòu)與算法學習之雙向鏈表

    雙向鏈表也叫雙鏈表,是鏈表的一種,它的每個數(shù)據(jù)結(jié)點中都有兩個指針,分別指向直接后繼和直接前驅(qū)。所以,從雙向鏈表中的任意一個結(jié)點開始,都可以很方便地訪問它的前驅(qū)結(jié)點和后繼結(jié)點。本文將為大家詳細介紹雙向鏈表的特點與使用,需要的可以參考一下
    2021-12-12
  • Spring Security+Spring Data Jpa如何進行安全管理

    Spring Security+Spring Data Jpa如何進行安全管理

    這篇文章主要介紹了Spring Security+Spring Data Jpa如何進行安全管理,幫助大家更好的理解和學習Spring Security框架,感興趣的朋友可以了解下
    2020-09-09
  • Java源碼解析之ConcurrentHashMap

    Java源碼解析之ConcurrentHashMap

    今天帶大家分析Java源碼,文中對Java ConcurrentHashMap介紹的非常詳細,有代碼示例,對正在學習Java的小伙伴們有很好的幫助,需要的朋友可以參考下
    2021-05-05
  • java中的三種取整函數(shù)總結(jié)

    java中的三種取整函數(shù)總結(jié)

    下面小編就為大家?guī)硪黄猨ava中的三種取整函數(shù)總結(jié)。希望對大家有所幫助。一起跟隨小編過來看看吧,祝大家游戲愉快哦
    2016-11-11

最新評論

津市市| 保靖县| 英德市| 商城县| 封丘县| 唐河县| 黎平县| 社会| 来安县| 安平县| 吴忠市| 山东| 屏东县| 佛坪县| 阿克| 鄯善县| 两当县| 桂平市| 蓬安县| 古交市| 巴中市| 平江县| 盐城市| 玉环县| 平原县| 宜昌市| 吴桥县| 汝州市| 丰原市| 项城市| 从江县| 丰宁| 建平县| 怀远县| 疏附县| 兰州市| 天长市| 六枝特区| 昭苏县| 界首市| 东台市|