Java基础之泛型

二次信任 提交于 2020-11-22 01:57:28

一:泛型技术的核心意义在于:

  类在定义的时候,可以使用一个标记,该标记就表示类中的属性或方法参数的类型,在使用的时候才动态的设置类型。

 1 package test;
 2 /**
 3  * 泛型的使用
 4  * @author Administrator
 5  *
 6  */
 7 public class TestType {
 8 
 9     public static void main(String[] args) {
10         TypeDemo<String> typeDemo = new TypeDemo<String>();//接受的是String类型
11         typeDemo.setX("东京260度");
12         typeDemo.setY("北纬79度");
13         System.out.println("x坐标为:"+typeDemo.getX()+"y坐标为:"+typeDemo.getY());//所以这里不需要向下转换,避免了Object向下转换的不安全性。
14     }
15 }
16 /**
17  * 泛型类,在类上 使用<T> 定义泛型,
18  * 确定了该类中所有参数的类型都必须跟类上定义的类型一致
19  * @author Administrator
20  *
21  * @param <T>
22  */
23 class TypeDemo<T>{
24     private T x;
25     private T y;
26     public void setX(T x) {
27         this.x = x;
28     }
29     public T getX() {
30         return x;
31     }
32     public void setY(T y) {
33         this.y = y;
34     }
35     public T getY() {
36         return y;
37     }
38 }

  注意:泛型的使用,能够采用的类型只能是类,也就是说不能是基本类型,必须是引用类型

  对于泛型的两点说明:

    》如果使用泛型类或者是接口时,没有设置泛型具体类型,那么会出现编译时的警告,同时为了保证程序的不出错,所有的泛型都将使用Object表示。

    》从JDK1.7开始可以简化泛型

1     public static void main(String[] args) {
2                                 //这里可以省略不写String
3         TypeDemo<String> typeDemo = new TypeDemo<>();
4         typeDemo.setX("东京260度");
5         typeDemo.setY("北纬79度");
6         System.out.println("x坐标为:"+typeDemo.getX()+"y坐标为:"+typeDemo.getY());
7     }

二:泛型(通配符)

  1、使用通配符  ?

 1 package test;
 2 /**
 3  * 泛型的使用
 4  * @author Administrator
 5  *
 6  */
 7 public class TestType {
 8 
 9     public static void main(String[] args) {
10                                                             //这里可以省略不写String
11         TypeDemo<String> typeDemo = new TypeDemo<>();
12         typeDemo.setX("东京260度");
13         typeDemo.setY("北纬79度");
14         System.out.println("------------------使用通配符?---------------");
15         fun(typeDemo);
16     }
17     
18     public static void fun(TypeDemo<?> typeDemo){
19         /**
20          * 使用通配符?号
21          * 可以使用该对象读到属性的值
22          * 但是不能够使用对象写属性的值
23          */
24         System.out.println("通过对象拿到x坐标的值为:"+typeDemo.getX());
25         System.out.println("通过对象拿到y坐标的值为:"+typeDemo.getY());
26     }
27 }
28 /**
29  * 泛型类,在类上 使用<T> 定义泛型,
30  * 确定了该类中所有参数的类型都必须跟类上定义的类型一致
31  * @author Administrator
32  *
33  * @param <T>
34  */
35 class TypeDemo<T>{
36     private T x;
37     private T y;
38     public void setX(T x) {
39         this.x = x;
40     }
41     public T getX() {
42         return x;
43     }
44     public void setY(T y) {
45         this.y = y;
46     }
47     public T getY() {
48         return y;
49     }
50 }

  2、在通配符 ? 基础上,还有两个子的通配符

    》一个为:? extends 类  :叫做设置泛型的上限,可以在声明上或是方法参数上使用。

    ? extends Number:意味着可以设置Number或者Number的子类(Integer、Long、Double。。。)

 1 package test;
 2 /**
 3  * 泛型的使用
 4  * @author Administrator
 5  *
 6  */
 7 public class TestType {
 8 
 9     public static void main(String[] args) {
10                                                             //这里可以省略不写String
11         TypeDemo<Float> typeDemo = new TypeDemo<>();
12         typeDemo.setX(30.05f);
13         typeDemo.setY(55.7f);
14         System.out.println("------------------使用通配符?---------------");
15         fun(typeDemo);
16     }
17     
18     public static void fun(TypeDemo<?> typeDemo){
19         /**
20          * 使用通配符?号
21          * 可以使用该对象读到属性的值
22          * 但是不能够使用对象写属性的值
23          */
24         System.out.println("通过对象拿到x坐标的值为:"+typeDemo.getX());
25         System.out.println("通过对象拿到y坐标的值为:"+typeDemo.getY());
26     }
27 }
28 
29 /**
30  *  泛型类,在类上 使用<T> 定义泛型,
31  * 确定了该类中所有参数的类型都必须跟类上定义的类型一致
32  * @author Administrator
33  *
34  * @param <T>
35  * 这里的T继承 Number,意味着,只能够设置为Number 或者是Number的子类
36  * 否则,变编译报错。
37  */
38 class TypeDemo<T extends Number>{
39     private T x;
40     private T y;
41     public void setX(T x) {
42         this.x = x;
43     }
44     public T getX() {
45         return x;
46     }
47     public void setY(T y) {
48         this.y = y;
49     }
50     public T getY() {
51         return y;
52     }
53 }

    》一个为:? super 类   :叫做设置泛型的下限,可以在方法参数上使用。

    ? super String:意味着只能够设置为String 或者是 String的父类 Object

 1 package test;
 2 /**
 3  * 泛型的使用
 4  * @author Administrator
 5  *
 6  */
 7 public class TestType {
 8 
 9     public static void main(String[] args) {
10                                                             //这里可以省略不写String
11         TypeDemo<String> typeDemo = new TypeDemo<>();
12         typeDemo.setX("30.05度");
13         typeDemo.setY("55.7度");
14         System.out.println("------------------使用通配符?---------------");
15         fun(typeDemo);
16     }
17     /**
18      * 这个方法这里使用 ? super String 表示只接受 String 或者是 String的父类 Object
19      * @param typeDemo
20      */
21     public static void fun(TypeDemo<? super String> typeDemo){
22         /**
23          * 使用通配符?号
24          * 可以使用该对象读到属性的值
25          * 但是不能够使用对象写属性的值
26          */
27         System.out.println("通过对象拿到x坐标的值为:"+typeDemo.getX());
28         System.out.println("通过对象拿到y坐标的值为:"+typeDemo.getY());
29     }
30 }
31 
32 /**
33  *  泛型类,在类上 使用<T> 定义泛型,
34  * 确定了该类中所有参数的类型都必须跟类上定义的类型一致
35  * @author Administrator
36  *
37  * @param <T>
38  */
39 class TypeDemo<T>{
40     private T x;
41     private T y;
42     public void setX(T x) {
43         this.x = x;
44     }
45     public T getX() {
46         return x;
47     }
48     public void setY(T y) {
49         this.y = y;
50     }
51     public T getY() {
52         return y;
53     }
54 }

  3、泛型接口

 1 package test;
 2 /**
 3  * 泛型的使用
 4  * @author Administrator
 5  *
 6  */
 7 public class TestType {
 8 
 9     public static void main(String[] args) {
10                                                             //这里可以省略不写String
11         TypeDemo<String> typeDemo = new TypeDemoImpl<>();
12         typeDemo.print("knock coding");
13         System.out.println("------------------泛型接口---------------");
14         TypeDemo<Integer> typeDemo2 = new TypeDemoImpl2();
15         typeDemo2.print(666);
16     }
17 }
18 
19 /**
20  * 泛型接口
21  * @author Administrator
22  * @param <T>
23  */
24 interface TypeDemo<T>{
25     public void print(T t);
26 }
27 
28 /**
29  * 定义接口的实现子类,有两种形式
30  * 方式一为:在子类上也继续使用父泛型的类型
31 */
32 class TypeDemoImpl<T> implements TypeDemo<T>{
33 
34     @Override
35     public void print(T t) {
36         System.out.println("方式一。。参数t的值为:"+t);
37     }
38     
39 }
40 /**
41  * 方式二:在子类实现接口时,接口明确的指出泛型的具体类型
42  * @author Administrator
43  */
44 class TypeDemoImpl2 implements TypeDemo<Integer>{
45 
46     @Override
47     public void print(Integer t) {
48         System.out.println("方式二。。参数t类型值为:"+t);
49     }
50     
51 }

  4、泛型方法不一定要定义在支持泛型的类里面

 1 package test;
 2 /**
 3  * 泛型的使用
 4  * @author Administrator
 5  *
 6  */
 7 public class TestType {
 8 
 9     public static void main(String[] args) {
10         String showInfo = showInfo("knock coding。。。");
11         System.out.println(showInfo.length());
12     }
13     /**
14      * 这里的泛型方法
15      * 返回值类型 T 与参数 T t 没有定义,
16      * 所以需要 在方法的返回值 之前加上<T>
17      * 而<T>具体的类型是由参数的类型来决定的
18      * @param t
19      * @return
20      */
21     public  static <T> T showInfo(T t){
22         return t;
23     }
24 }

  5、总结泛型

    总之泛型解决的是向下转型所带来的的安全问题,其核心的组成就是在声明类或接口的时候不指定参数或者属性的类型;

    “?”可以接受任意的泛型类型,只能够取出,但是不能修改。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!