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){}
注意
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); } }
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); } }
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"); } }
Comparator
对象进行自然方式排序,必须是实现了Comparable接口的。
Arrays.sort(数组);//默认 自然排序
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 }
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 }
2.对象默认是public static final的
3.枚举类的构造都是private的
4.枚举类继承自java.lang.Enum类
5.对于一个非抽象枚举类来说,都是final
枚举类中定义抽象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();// } }