1、泛型类定义的泛型,在整个类中有效。如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。
2、为了让不同方法可以操作不同类型,而且类型还不确定。那么可以将泛型定义在方法上。
3、特殊之处:
静态方法不可以访问类上定义的泛型。
如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。
package tan; //定义泛型类(要操作的类型不确定) class Demo<T>{ public void show(T t){ System.out.println("show:"+t); } //方法中定义泛型 public <Q> void print(Q q){ System.out.println("pirnt:"+q); } //静态方法中定义泛型 public static <G> void method(G g){ System.out.println("mentod:"+g); } } public class GenericDemo1 { public static void main(String[] args) { Demo<String> d=new Demo<String>(); d.show("beijing"); //d.show(6); 编译失败,因为show方法会随着对象的类型,对象是什么类型的,show方法中就只能接受什么类型 d.print(888);//将泛型定义在方法上传什么类型都可以 d.print("tan"); //类名调用静态方法 Demo.method("IT Dreamer"); } }
4、将泛型定义在接口上
5、? 通配符。也可以理解为占位符。package tan; //将泛型定义在接口上 interface Inter<T>{ public void show(T t); } //确定操作类型 /*class InterImpl implements Inter<String>{ @Override public void show(String t) { System.out.println("show-----"+t); } }*/ //方式二:实现接口以后仍然不知操作类型时 class InterImpl<T> implements Inter<T>{ @Override public void show(T t) { System.out.println("show-----"+t); } } public class GenericDemo2 { public static void main(String[] args) { /*InterImpl impl=new InterImpl(); impl.show("Great");*/ InterImpl<Integer> i = new InterImpl<Integer>(); i.show(4); } }
6、泛型限定package tan; import java.util.*; public class GenericDemo3 { public static void main(String[] args) { ArrayList<String> al = new ArrayList<String>(); al.add("abc1"); al.add("abc2"); al.add("abc3"); ArrayList<Integer> al1 = new ArrayList<Integer>(); al1.add(4); al1.add(7); al1.add(1); printColl(al); printColl(al1); } //1、不明确类型用占位符表示 public static void printColl(ArrayList<?> al){ Iterator<?> it = al.iterator(); while(it.hasNext()) { System.out.println(it.next().toString()); } } //2、也可以用下面这种方式:如果T是一个具体类型的话,可以接收并操作具体类型 public static <T>void printColl2(ArrayList<T> al){ Iterator<T> it = al.iterator(); while(it.hasNext()) { T t=it.next(); System.out.println(t); } } }
? extends E: 可以接收E类型或者E的子类型。上限。
? super E: 可以接收E类型或者E的父类型。 下限
上限示例:
package xiao; import java.util.*; public class GenericDemo3 { public static void main(String[] args) { ArrayList<Person> al = new ArrayList<Person>(); al.add(new Person("tan11")); al.add(new Person("tan13")); al.add(new Person("tan21")); ArrayList<Student> al1 = new ArrayList<Student>(); al1.add(new Student("stu01")); al1.add(new Student("stu02")); al1.add(new Student("stu03")); printColl(al); System.out.println(); printColl2(al); printColl2(al1); } // 1、只能打印父类类型 public static void printColl(ArrayList<Person> al) { Iterator<Person> it = al.iterator(); while (it.hasNext()) { System.out.println(it.next().getName()); } } // 2.既可以打印父类也可以打印子类类型 《 上限》? extends E: 可以接收E类型或者E的子类型 public static void printColl2(ArrayList<? extends Person> al) { Iterator<? extends Person> it = al.iterator(); while (it.hasNext()) { System.out.println(it.next().getName()); } } } class Person { private String name; Person(String name) { this.name = name; } public String getName() { return name; } } class Student extends Person { Student(String name) { super(name); } } /* class Student implements Comparable<Person>//<? super E> { public int compareTo(Person s) { this.getName() }*/
下限示例:
package zheng; import java.util.Comparator; import java.util.Iterator; import java.util.TreeSet; public class GenericDemo5 { public static void main(String[] args) { TreeSet<Student> ts = new TreeSet<Student>(new Comp()); ts.add(new Student("abc1")); ts.add(new Student("abc2")); ts.add(new Student("abc3")); Iterator<Student> it = ts.iterator(); while(it.hasNext()) { System.out.println(it.next().getName()); } } } class Person { private String name; Person(String name) { this.name = name; } public String getName() { return name; } } class Student extends Person { Student(String name) { super(name); } } class Comp implements Comparator<Person>//<? super E> { public int compare(Person s1,Person s2) { //Person s1 = new Student("abc1"); return s1.getName().compareTo(s2.getName()); } }
建立通用的比较器方法
package Qiang; import java.util.*; class GenericDemo4 { public static void main(String[] args) { TreeSet<Student> ts = new TreeSet<Student>(new Comp()); ts.add(new Student("abc03")); ts.add(new Student("abc02")); ts.add(new Student("abc06")); ts.add(new Student("abc01")); Iterator<Student> it = ts.iterator(); while(it.hasNext()) { System.out.println(it.next().getName()); } TreeSet<Worker> ts1 = new TreeSet<Worker>(new Comp()); ts1.add(new Worker("wabc--03")); ts1.add(new Worker("wabc--02")); ts1.add(new Worker("wabc--06")); ts1.add(new Worker("wabc--01")); Iterator<Worker> it1 = ts1.iterator(); while(it1.hasNext()) { System.out.println(it1.next().getName()); } } } //比较器是通用的, class Comp implements Comparator<Person> { public int compare(Person p1,Person p2) { //只能使用父类中的方法,有扩展性就有局限性 return p2.getName().compareTo(p1.getName()); } } class Person { private String name; Person(String name) { this.name = name; } public String getName() { return name; } public String toString() { return "person :"+name; } } class Student extends Person { Student(String name) { super(name); } } class Worker extends Person { Worker(String name) { super(name); } }