Day13 泛型

泛型

泛型定义

在一个类型(类,接口,方法)之后,定义一个类型参数。

原生类型:类型后面没有指定具体的类型参数。

好处

使用泛型的好处在于,它在编译的时候进行类型安全检查,并且在运行时所有的转换都是强制的,隐式的,大大提高了代码的重用率。

语法

class Point<T>{}

通配符(?)

无界通配符(?)可以接受任何的类类型。

public void show(Point<?> p){}

(? extends 上限类)只能接受上限类和上限类子类,如只能接受数字类型,Byte,Short,Integer,Long,Float,Double

public void show(Point<? extends Number> p){}

(? super 下限类)下限,下限类和下限类的父类,Number和Number的父类

public void show(Point<? super Number> p){}

注意

Point<Object>不是Point<String>、Point<Integer>等的父类

public void add(Point<String> ps,Point<Object> po){//错误
  po = ps
}

public void add(Point<String> ps,Point<? extends Object> po){//正确

类型参数与通配符的区别

类型参数与 通配符的区别:
<T> 和 <?>
1.类型参数可以指定上限,也只能指定上限;
统配符可以指定上限,也可以指定下限;
2.类型参数 可以指定多个 上限;
通配符 只能指定一个上限;
3.类型参数 可以作为一种类型存在;
统配符不能表示 类型

泛型构造

//定义了一个泛型类 
class PointN<T>{//类型参数 形式类型参数 
    private T x;
    private T y;
    //定义了一个泛型构造器
    <E>PointN(E e){
        System.out.println(e);
    }
    public T getX() {
        return x;
    }
    public void setX(T x) {
        this.x = x;
    }
    public T getY() {
        return y;
    }
    public void setY(T y) {
        this.y = y;
    }
}
public class TestPoint2 {
    public static void main(String[] args) {
        //                        指定具体的类型参数
        PointN<String> p1 = new <Integer>PointN<String>(22);
        //类型推断:   根据参数  的类型 自动推断出 构造的类型参数 是Integer类型
        PointN<String> p2 = new PointN<String>(22);
    }

}

泛型方法

定义泛型方法时,必须在返回值前边加一个<T>,来声明这是一个泛型方法,持有一个泛型T,然后才可以用泛型T作为方法的返回值。

class Demo{
    //泛型方法
    public <E> void f(E e) {
        System.out.println(e);
    }
    public <E> E ff(E e) {
        return e;
    }
    public <E extends Number> void fff(E e) {
        System.out.println(e);
        //自动推断的方式
        f("hello");
        //指定的方式,显示,this
        this.<String>f("hello");
    }
}
public class TestPoint3 {
    public static void main(String[] args) {
        // 泛型方法应用
        Demo d = new Demo();
        //具体指定 泛型方法参数的类型
        d.<String>f("hello");
        //可以使用类型推断: 根据参数的类型 自动推断
        d.f(11);
        d.fff(33);

    }

}

泛型擦除

1.参数化类型:Point<String>,擦除后为原生类型Point

2.类型参数:用上界来替换

  • Point<T>:无界类型参数,用Object来替换

  • 类型参数有上限,用上限来替换。

  • 有多个上限,用第一个上限替换。

重载

class PointNew<T>{}
interface Info1{}
interface Info2{}

class Demo1{
    //为了实现重载
    //生成的字节码文件中,泛型的信息被擦除了
    public void f(String p) {}
    public void f(PointNew<Integer> p) {}//擦除后:PointNew p
    public <E> void f(E e) {}//擦除后:Object e
    public <E extends Info1> void f(E e) {}//擦除后:Info1 e
    public <E extends Info2 & Info1> void f(E e) {}//擦除后:Info2 e
    
}

重写

class Parent{
    //重写:参数父类中参数擦除后与子类中参数相同
    public void f(PointNew<String> p) {}
}
class Child1 extends Parent{
    public void f(PointNew<String> p) {}
}

泛型接口

//泛型接口
interface Info<T>{
    void f(T t);
}
//在实现接口时  指定具体的类型参数
class InfoImpl1 implements Info<String>{
    @Override
    public void f(String t) {
        System.out.println(t);
    }
}
//在实现 接口时  不能确定类型
class InfoImpl2<T> implements Info<T>{
    @Override
    public void f(T t) {
        System.out.println(t);
    }
}
public class TestPoint5 {

    public static void main(String[] args) {
        InfoImpl1 i1 = new InfoImpl1();
        i1.f("hello");
        InfoImpl2<String> i2 = new InfoImpl2<>();
        i2.f("tom");
    }

}

比较器

Comparable

Comparator

对象进行自然方式排序,必须是实现了Comparable接口的。

Arrays.sort(数组);//默认 自然排序

Comparable<T> 泛型接口 比较器实现自然排序

Comparator<T> 泛型接口 外部比较器

 1 package day13;
 2 
 3 import java.util.Arrays;
 4 import java.util.Comparator;
 5 class Student implements Comparable<Student>{
 6     private int age;
 7     private int no;
 8     public Student(int no,int age) {
 9         this.age = age;
10         this.no= no;
11     }
12     public int getAge() {
13         return age;
14     }
15     public int getNo() {
16         return no;
17     }
18     @Override
19     public String toString() {
20         return "编号:"+no+",年龄:"+age;
21     }
22 /*    @Override
23     public int compareTo(Object o) {
24         //this 与  o比较
25         //this.age   o.age
26         Student stu = (Student)o;
27         //this.age  stu.age
28         
29         return 0;
30     }*/
31     @Override
32     public int compareTo(Student o) {
33         // this.age   o.age
34         //升序的方式 
35         /*if(this.age > o.age ) {
36             return 1;//正数
37         }else if(this.age < o.age) {
38             return -1;//负数
39         }else {
40             return 0;//相等
41         }*/
42         return this.age - o.age;
43     }    
44 }
45 //按照 编号升序排序
46 class NoComparator implements Comparator<Student>{
47     @Override
48     public int compare(Student o1, Student o2) {
49         // o1  和 o2比较
50 /*        if(o1.getNo() > o2.getNo()) {
51             return 1;
52         }else if(o1.getNo() < o2.getNo()) {
53             return -1;
54         }else {
55             return 0;
56         }*/
57         return o1.getNo()- o2.getNo();
58     }    
59 }
60 public class TestSort {
61     public static void main(String[] args) {
62         Student zhang = new Student(2,44);
63         Student wang = new Student(1,11);
64         Student zhao = new Student(3,33);
65         Student [] stus = {zhang,wang,zhao};
66         //Arrays.sort()按照自然方式排序的
67 //        Arrays.sort(stus);
68         //1.自定义类 实现接口
69 //        Arrays.sort(stus, new NoComparator());
70         //2.匿名内部类实现接口
71         Arrays.sort(stus,new Comparator<Student>() {
72             @Override
73             public int compare(Student o1, Student o2) {
74                 return o1.getNo() - o2.getNo();
75             }    
76         });
77         //3 Lambda
78         Arrays.sort(stus,(s1,s2)->s1.getNo()-s2.getNo());
79         
80         Arrays.stream(stus).forEach(System.out::println);
81         //--------------------------------------------
82         int [] arr = {45,1,77,34,3};
83         Arrays.sort(arr);
84         Arrays.stream(arr).forEach(System.out::println);
85         //--------------------------------------------
86         String [] arrs = {"cc","dd","aa","ee"};
87         Arrays.sort(arrs);
88         Arrays.stream(arrs).forEach(System.out::println);
89         //------------------------------------------------
90     }
91 
92 }
View Code

枚举类型

语法

enum 枚举类型{
  
}
  1 package day13;
  2 
  3 import java.util.Scanner;
  4 
  5 //RGB
  6 /*class Color{
  7     public static final int RED = 1;
  8     public static final int GREEN = 2;
  9     public static final int BLUE = 3;
 10 }*/
 11 interface ColorInfo{
 12     void fv();//抽象方法
 13 }
 14 enum Color{
 15     RED(1,"红色") {
 16         @Override
 17         void f() {
 18             // TODO Auto-generated method stub
 19             
 20         }
 21     },GREEN(2,"绿色") {
 22         @Override
 23         void f() {
 24             // TODO Auto-generated method stub
 25             
 26         }
 27     },BLUE(3,"蓝色") {
 28         @Override
 29         void f() {
 30             // TODO Auto-generated method stub
 31             
 32         }
 33     };
 34     
 35     private Color(int no, String name) {
 36         this.no = no;
 37         this.name = name;
 38     }
 39     private int no;
 40     private String name;
 41     //抽象方法
 42     abstract void f();
 43 }
 44 /*enum Color implements ColorInfo{
 45     //定义枚举成员,对象,实例
 46     RED(1,"红色"){
 47         public void fv() {
 48             System.out.println("红色的");
 49         }
 50     },GREEN(2,"绿色"){
 51         public void fv() {
 52             System.out.println("绿色的");
 53         }
 54     },BLUE(3,"蓝色"){
 55         public void fv() {
 56             System.out.println("蓝色的");
 57         }
 58     };    //public static final
 59     private int no;//编号
 60     private String name;//名字
 61     
 62     private Color(int no, String name) {
 63         this.no = no;
 64         this.name = name;
 65     }
 66     public int getNo() {
 67         return no;
 68     }
 69     public void setNo(int no) {
 70         this.no = no;
 71     }
 72     public String getName() {
 73         return name;
 74     }
 75     public void setName(String name) {
 76         this.name = name;
 77     }
 78     public void f() {}
 79     @Override
 80     public String toString() {
 81         // TODO Auto-generated method stub
 82         return this.no+","+this.name();
 83     }
 84     @Override
 85     public void fv() {
 86         // TODO Auto-generated method stub
 87         
 88     }
 89     
 90 }*/
 91 public class TestEnum {
 92     public static void main(String[] args) {
 93 //        System.out.println(Color.RED.getNo()+","+Color.RED.getName());
 94 //        System.out.println(Color.BLUE.getNo()+","+Color.BLUE.getName());
 95 /*        Color.RED.setName("红色");
 96         System.out.println(Color.RED.getName());
 97         Color.RED.f();*/
 98     /*    Color.RED.no = 11;
 99         Color.GREEN.name = "绿色";
100         System.out.println(Color.RED.no);
101         System.out.println(Color.GREEN.name);*/
102         
103 /*        Scanner input = new Scanner(System.in);
104         System.out.println("输入一个颜色:");
105         String s = input.next();
106         Color co = Color.valueOf(s); 
107         switch(co) {
108         case RED:
109             System.out.println("进行红色的操作");
110             break;
111         case GREEN:
112             System.out.println("进行绿色的操作");
113             break;
114         case BLUE:
115             System.out.println("进行蓝色的操作");
116             break;
117         }*/
118         
119         //可以遍历枚举值
120 /*        for(Color c: Color.values()) {
121             System.out.println(c.name());
122             System.out.println(c.ordinal());
123         }*/
124         
125 /*        // 类型不安全
126         int red = Color.RED;
127         int a = red +5;
128         System.out.println(a);
129         //意思不明确
130         System.out.println(Color.RED);*/
131 //        System.out.println(Color.RED);
132         
133         
134         
135         
136 
137     }
138 
139 }
View Code

注意

1.所有的枚举类型的对象都在枚举类第一行显示定义出来。

2.对象默认是public static final的

3.枚举类的构造都是private的

4.枚举类继承自java.lang.Enum类

5.对于一个非抽象枚举类来说,都是final

一个枚举类的所有对象都实现了接口中的抽象方法,此枚举类就是抽象类,abstract的了

枚举类中定义抽象abstract方法,所有对象都需要实现此抽象方法,那么此枚举类是abstract的了

强制垃圾回收

class Person{

    @Override
    protected void finalize() throws Throwable {
        System.out.println("this---->"+this);
    }
    
}
public class TestGC {

    public static void main(String[] args) {
        // 强制垃圾回收
        Person per = new Person();
        System.out.println(per);
        per = null;//断开引用
        System.gc();//强制通知垃圾回收器
//        Runtime.getRuntime().gc();//

    }

}
原文地址:https://www.cnblogs.com/qingyunzong/p/8253587.html