一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - Java教程 - java泛型基本知識及通用方法

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

2021-07-28 11:29眺望小寒山 Java教程

這篇文章主要介紹了java泛型基礎知識及通用方法,從以下幾個方面介紹一下java的泛型: 基礎, 泛型關鍵字, 泛型方法, 泛型類和接口,感興趣的可以了解一下

泛型的基本使用

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

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

基礎:

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

?
1
2
3
4
5
6
public void testbasis(){
 list<string> list = new arraylist<string>();
// new arraylist<int>();
 }
 
 //這是最基本的泛型使用, 就不多說了, 不過要注意的是泛型只能是引用數據類型, 不能是基本類型, 而且泛型只在編譯期有效, 在編譯后的class文件中是不存在泛型信息的

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

泛型關鍵字:

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public void testkeyword() throws exception {
 //實例化參數類型必須指明具體類型
 list<?> list = new arraylist<string>();
 //由于list中類型不明確, 所以不能進行添加操作
// list.add("sk");
 
 //通配符?表示任意引用類型
 list<list<?>> list1 = new arraylist<list<?>>();
 //list1的參數化類型是一個list, 而這個list也是一個參數化類型, 它的類型是任意類型, 所以list1可以添加任意list類型對象
 list1.add(new arraylist<object>());
 list1.add(new arraylist<string>());
 
 //實例化list2時指明了類型參數list, 只不過這個list是一個泛型類型
 //從這里可以看到關鍵字extends的用法, 其實就是繼承, 如下這里的list2中的參數化類型list(在這里記為paramlist)的參數化類型是繼承自number的
 //所以在list2在添加的時候只能添加參數化類型為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關鍵字, 所以不能添加number的父類
 
 //相信大家也猜到了, 既然extends關鍵字表示子類及其本身, 那么super關鍵字是表示父類及其本身, 是的, 沒錯
 //和上面的不一樣了, l1不能添加, 因為integer是number的子類, 并不是number的父類
 list<list<? super number>> list3 = new arraylist<list<? super number>>();
// list3.add(l1); //這里使用了super關鍵字, 所以不能添加number的子類
 list3.add(l2);
 list3.add(l3);
 }

泛型方法:

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//無返回值有參的方法, 參數為泛型
 public <t> void show(t t){
 system.out.println("t-=-=" + t);
 }
 
 //有返回值的有參方法, 只有一個參數化類型, 這里定義泛型的方式和上面一樣, 也是先定義后使用, 只不過這里的返回類型是泛型
 public <t> t get(t t){
 return t;
 }
 
 //有返回值的有參方法, 有多個參數化類型, 這里以兩個為例
 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));
 }

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

泛型類和接口:

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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);
 }
}

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

  如果是在繼承或實現中, 可以在子類或實現類中確定具體類型

使用java泛型設計通用方法

泛型是java se 1.5的新特性, 泛型的本質是參數化類型, 也就是說所操作的數據類型被指定為一個參數. 因此我們可以利用泛型和反射來設計一些通用方法. 現在有2張表, 一張user表和一張student表.

user:

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

student:

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

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

  user的實體類:

?
1
2
3
4
5
private integer id;
 private string username;
 private string password;
 private string hobby;
 //getxxx方法和setxxx方法

  student實體類:

?
1
2
3
4
private integer id;
private string name;
private integer age;
//getxxx方法和setxxx方法

  basedao接口:

?
1
2
3
4
public interface basedao<t> {
 //根據id查詢的方法
 t findbyid(integer id);
}

  basedaoimpl類, 實現了basedao接口, 通用方法就在這里面完成:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//設置為抽象的, 不讓他實例化, 讓其子類實例化就行了
//通過泛型設計通用方法的關鍵就是利用反射拿到泛型的具體類型
public abstract class basedaoimpl<t> implements basedao<t> {
 private string tablename;  //表名
 private class<t> actualtype;//真實類型
 
 /**
 * findbyid(integer id)這個方法被子類繼承了, 假設我們在userdaoimpl中操作, 此時參數化類型t為user
 * 下面的講解都假設是在userdaoimpl中進行的
 */
 //把公共部分可以放到構造方法中
 @suppresswarnings("unchecked")
 public basedaoimpl() {
 //返回類型是type 是 java 編程語言中所有類型的公共高級接口. 它們包括原始類型、參數化類型、數組類型、類型變量和基本類型.
 //type的已知子接口: parameterizedtype 表示參數化類型, 如 collection<string>.
 //getclass()得到userdaoimpl的class, 得到class一般有3中方式: getclass(), 類名.class, class.forname()
 type type = getclass().getgenericsuperclass();//獲取userdaoimpl<user>的參數化類型的父類basedaoimpl<user>
 //由于我們得到的是一個參數化類型, 所以轉成parameterizedtype, 因為需要使用里面的方法
 parameterizedtype pt = (parameterizedtype) type;//強轉
 type[] actualtypearr = pt.getactualtypearguments();//獲取真實參數類型數組[user.class], 可以調試看到這里的值
 actualtype = (class<t>) actualtypearr[0];//數組只有一個元素
 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;
 }
}

  連接數據庫操作是用的c3p0和dbutils, 有關這方面的內容可以參看我以前的隨筆.     

  userdao接口, 繼承basedao接口:

?
1
2
public interface userdao<t> extends basedao<t> {
}

  userdaoimpl類, 實現userdao接口, 繼承basedaoimpl類, 可以看到里面什么方法也沒有:

?
1
2
public class userdaoimpl extends basedaoimpl<user> implements userdao<user> {
}

  studentdao接口, 繼承basedao接口:

?
1
2
public interface studentdao<t> extends basedao<t> {
}

  studentdaoimpl類, 實現studentdao接口, 繼承basedaoimpl類, 也可以看到里面什么方法也沒有:

?
1
2
public class studentdaoimpl extends basedaoimpl<student> implements studentdao<student> {
}

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

測試:

?
1
2
3
4
5
6
7
8
9
@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));
 }

  看一下測試的結果: 同一個方法把2張表中的數據都查出來了

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日韩精品福利视频一区二区三区 | 亚洲一区二区成人 | 亚洲精品视 | 男男playh片在线观看 | 国内视频一区二区三区 | 亚洲成aⅴ人片在线 | 亚洲a图| 十六以下岁女子毛片免费 | 手机跑分排行最新排名 | 亚洲成年网站在线观看 | 男人女人日皮视频 | 欧美日韩亚洲另类人人澡 | 91视频无限看 | 亚洲欧美日韩综合在线 | chinese特色video | 99久久国产视频 | 男gay网站视频免费观看 | 含羞草传媒网站免费进入欢迎 | 亚洲欧美久久久久久久久久爽网站 | 小舞同人18av黄漫网站 | 97社区| 湖南美女被黑人4p到惨叫 | 男人疯狂擦进女人下面 | caoporen在线视频入口 | 亚洲区精品久久一区二区三区 | 成人私人影院在线版 | 无码毛片内射白浆视频 | 男人j桶进女人p桶爽 | 91国产高清 | 插得爽| 91tv在线观看| 91精品国产高清久久久久久io | 亚洲欧洲综合 | 亚洲天堂在线视频播放 | 亚洲精品国产SUV | 欧美xxxxxbb| 男女做受快插大片 | 久久99精品国产免费观看 | 66j8影院xxxx深夜 | 高h喷水荡肉爽文np肉色文 | 香港论理午夜电影网 |