/**
* @author Jason
* @create 2020-07-11 10:57
* 普通集合存在的问题
*/
public class GenericityTest01 {
public static void main(String[] args) {
Collection list = new ArrayList();
list.add("Jason");
list.add("Jack");
list.add(222);
//创建一个迭代器
Iterator it = list.iterator();
while (it.hasNext()) {
//将集合中的内容强制转换
String o =(String) it.next();
//打印出他们各自的长度
System.out.println(o.length());
}
}
}
控制台输出:
5
4
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at GenericityTest01.main(GenericityTest01.java:17)
2、使用泛型的情况
/**
* @author Jason
* @create 2020-07-11 11:47
* 泛型实例
*/
public class GenericityTest04 {
public static void main(String[] args) {
Collection list = new ArrayList();
list.add("Jason");
list.add("Jack");
//list.add(222);
//创建一个迭代器
Iterator it = list.iterator();
while (it.hasNext()) {
//将集合中的内容强制转换
String o = (String) it.next();
//打印出他们各自的长度
System.out.println(o.length());
}
}
}
控制台输出:
5
4
3、新的问题
/**
* @author Jason
* @create 2020-07-11 14:49
*
*/
public class MyClass {
public static void main(String[] args) {
GenericityTest05 strgeneric = new GenericityTest05<>("jason");
String key1 = strgeneric.getKey();
System.out.println("key1:" + key1);
System.out.println("----------");
GenericityTest05 intgeneric = new GenericityTest05<>(111);
Integer key2 = intgeneric.getKey();
System.out.println("key2:" + key2);
}
}
**
* @author Jason
* @create 2020-07-11 14:42
*/
public class GenericityTest05 {
private T key;
public GenericityTest05() {
}
public GenericityTest05(T key) {
this.key = key;
}
public T getKey() {
return key;
}
public void setKey(T key) {
this.key = key;
}
@Override
public String toString() {
return "GenericityTest05{" +
"key=" + key +
'}';
}
}
控制台输出:
key1:jason
----------
key2:111
/**
* @author Jason
* @create 2020-07-11 15:12
* 年会抽奖器
*/
public class ProductGetter {
Random random = new Random();
//奖品
private T product;
//奖品池
ArrayList list = new ArrayList<>();
//添加奖品
public void addProduct(T t) {
list.add(t);
}
//抽奖
public T getProduct(){
product = list.get(random.nextInt(list.size()));
return product;
}
public static void main(String[] args) {
//创建抽奖器对象
ProductGetter strProduct = new ProductGetter<>();
String[] strProducts = {"Apple", "HuaWei", "XiaoMi", "SanXing"};
//给抽奖器中添加奖品
for (int i = 0; i < strProducts.length; i++) {
strProduct.addProduct(strProducts[i]);
}
//抽奖
String product1 = strProduct.getProduct();
System.out.println("恭喜您抽中了:"+product1);
System.out.println("---------------");
ProductGetter intProduct = new ProductGetter<>();
int[] intProducts = {1000, 2000, 3000, 5000};
for (int i = 0; i < intProducts.length; i++) {
intProduct.addProduct(intProducts[i]);
}
Integer product2 = intProduct.getProduct();
System.out.println("恭喜您抽中了:"+product2);
}
}
(5)从泛型类派生子类
/**
* @author Jason
* @create 2020-07-11 15:36
*/
public class Parent {
private E value;
public E getValue() {
return value;
}
public void setValue(E value) {
this.value = value;
}
}
/**
* @author Jason
* @create 2020-07-11 15:39
* 子类也是泛型类
*/
public class ChildFirst extends Parent {
@Override
public T getValue() {
return super.getValue();
}
}
/**
* @author Jason
* @create 2020-07-11 15:41
*/
public class MyClass {
public static void main(String[] args) {
ChildFirst childFirst = new ChildFirst();
childFirst.setValue("Jason");
String value = childFirst.getValue();
System.out.println(value);
}
}
• 子类不是泛型类,父类要明确泛型的数据类型
class ChildGeneric extends Generic
/**
* @author Jason
* @create 2020-07-11 15:36
*/
public class Parent {
private E value;
public E getValue() {
return value;
}
public void setValue(E value) {
this.value = value;
}
}
/**
* @author Jason
* @create 2020-07-11 15:48
* 泛型类派生子类,如果子类不是泛型类,那么父类要明确数据类型(创建子类的时候无法确定父类类型)
*/
public class ChildSecond extends Parent {
@Override
public Integer getValue() {
return super.getValue();
}
@Override
public void setValue(Integer value) {
super.setValue(value);
}
}
/**
* @author Jason
* @create 2020-07-11 15:41
*/
public class MyClass {
public static void main(String[] args) {
ChildSecond childSecond = new ChildSecond();
childSecond.setValue(100);
Integer value1 = childSecond.getValue();
System.out.println(value1);
}
}
interface 接口名称 <泛型标识,泛型标识,…> {
泛型标识 方法名();
.....
}
2、泛型接口详情
/**
* @author Jason
* @create 2020-07-11 16:08
* 泛型接口
*/
public interface Generator {
T getKey();
}
/**
* @author Jason
* @create 2020-07-11 16:11
* 实现泛型接口的类不是泛型类,需要明确实现泛型接口的数据类型
*/
public class Apple implements Generator {
@Override
public String getKey() {
return "Hello Jason!";
}
}
/**
* @author Jason
* @create 2020-07-11 16:13
*/
public class Test {
public static void main(String[] args) {
Apple apple = new Apple();
String key = apple.getKey();
System.out.println(key);
}
}
/**
* @author Jason
* @create 2020-07-11 16:08
* 泛型接口
*/
public interface Generator {
T getKey();
}
/**
* @author Jason
* @create 2020-07-11 16:17
* 泛型类实现泛型接口,需要保证实现接口的泛型类的泛型标识包含泛型接口的泛型标识
*/
public class Pair implements Generator {
private T key;
private E value;
public Pair(T key, E value) {
this.key = key;
this.value = value;
}
@Override
public T getKey() {
return key;
}
public E getValue() {
return value;
}
}
/**
* @author Jason
* @create 2020-07-11 16:13
*/
public class Test {
public static void main(String[] args) {
Pair pair = new Pair<>("count",100);
String key1 = pair.getKey();
Integer value = pair.getValue();
System.out.println(key1 + " = " + value);
}
}
/**
* @author Jason
* @create 2020-07-11 15:12
* 年会抽奖器
*/
public class ProductGetter {
Random random = new Random();
//奖品
private T product;
//奖品池
ArrayList list = new ArrayList<>();
//添加奖品
public void addProduct(T t) {
list.add(t);
}
//抽奖方法
public T getProduct(){
product = list.get(random.nextInt(list.size()));
return product;
}
//定义泛型方法
public E getProduct(ArrayList list) {
return list.get(random.nextInt(list.size()));
}
//静态方法方法,采用多个泛型类型
public static void printType(T t, E e, K k) {
System.out.println(t + "\t" + t.getClass().getSimpleName());
System.out.println(e + "\t" + e.getClass().getSimpleName());
System.out.println(k + "\t" + k.getClass().getSimpleName());
}
//泛型可变参数的定义
public static void print(E... e) {
for (int i = 0; i < e.length; i++) {
System.out.println(e[i]);
}
}
public static void main(String[] args) {
ProductGetter productGetter = new ProductGetter<>();
ProductGetter intProduct = new ProductGetter<>();
int[] intProducts = {1000, 2000, 3000, 5000};
for (int i = 0; i < intProducts.length; i++) {
intProduct.addProduct(intProducts[i]);
}
//泛型类的成员方法的调用
Integer product2 = intProduct.getProduct();
System.out.println("恭喜您抽中了:"+product2);
System.out.println(product2+"\t"+product2.getClass().getSimpleName());
System.out.println("+++++++++++++++++");
ArrayList strArrayList = new ArrayList<>();
strArrayList.add("笔记本电脑");
strArrayList.add("苹果电脑");
strArrayList.add("华为手机");
strArrayList.add("ipad");
//泛型方法的调用,类型通过调用方法的时候来指定
String product = productGetter.getProduct(strArrayList);
System.out.println(product+"\t"+product.getClass().getSimpleName());
System.out.println("+++++++++++++++++");
ArrayList intArrayList = new ArrayList<>();
intArrayList.add(1000);
intArrayList.add(2000);
intArrayList.add(3000);
intArrayList.add(5000);
Integer product3 = productGetter.getProduct(intArrayList);
System.out.println(product3+"\t"+product3.getClass().getSimpleName());
System.out.println("----------------");
//调用多个泛型类型的静态泛型方法
productGetter.printType(100,"jason",true);
System.out.println("----------------");
//调用可变参数
productGetter.print(1, 2, 3, 4);
System.out.println("----------------");
productGetter.print("a","b","c");
}
}
5、总结
/**
* @author Jason
* @create 2020-07-12 8:05
*/
public class Box {
private E first;
public E getFirst() {
return first;
}
public void setFirst(E first) {
this.first = first;
}
}
/**
* @author Jason
* @create 2020-07-12 8:06
* 通配符
*/
public class Test04 {
public static void main(String[] args) {
Box box = new Box<>();
box.setFirst(100);
showBox(box);
//如果此时我们想传一个Integer类型的肯定会报错
//即使showBox方法是Number类型或者Integer类型都是不可以的
/*Box box1 = new Box<>();
box1.setFirst(200);
showBox(box1);*/
//如果此时我们在showBox上使用通配符会怎么样呢?当然问题就解决了
Box box1 = new Box<>();
box1.setFirst(200);
showBox(box1);
}
/*public static void showBox(Box box){
Number first = box.getFirst();
System.out.println(first);
}*/
//这里虽然是换了通配符,但是还是会存在一个问题,需要用Object类型接收
public static void showBox(Box> box){
Object first = box.getFirst();
System.out.println(first);
}
}
2、通配符上限
public class Animal {
}
public class Cat extends Animal {
}
public class MiniCat extends Cat {
}
/**
* @author Jason
* @create 2020-07-12 8:33
* 通配符上限
*/
public class TestUp {
public static void main(String[] args) {
ArrayList animals = new ArrayList<>();
ArrayList cats = new ArrayList<>();
ArrayList miniCats = new ArrayList<>();
//这里为啥可以添加呢?原因在于他的底层源码:public boolean addAll(Collection extends E> c)
cats.addAll(cats);
cats.addAll(miniCats);
//这里会报异常:原因是什么呢?问题在于showAnimal()采用的是通配符上限
//showAnimal(animals);
showAnimal(cats);
showAnimal(miniCats);
}
//泛型通配符上限,传递的集合类型,只能是Cat或Cat的子类
public static void showAnimal(ArrayList extends Cat> list) {
//这里是不可以添加元素的,因为ArrayList是上限通配符,此时我们是无法知道他存的是何种类型的元素
/*list.add(new Animal());
list.add(new Cat());*/
for (int i = 0; i < list.size(); i++) {
Cat cat = list.get(i);
}
}
}
3、通配符下限
/**
* @author Jason
* @create 2020-07-12 8:57
* 通配符下限
*/
public class TestDown {
public static void main(String[] args) {
ArrayList animals = new ArrayList<>();
ArrayList cats = new ArrayList<>();
ArrayList miniCats = new ArrayList<>();
//集合只能是Cat或Cat的父类类型,不能是它的子类型
showAnimal(animals);
showAnimal(cats);
//showAnimal(miniCats);
}
//类型通配符下限,要求集合只能是Cat或Cat的父类类型
public static void showAnimal(List super Cat> list) {
//这里可以添加元素,并且他本身和子类都能添加,for循环是object类型接收的
list.add(new Cat());
list.add(new MiniCat());
//list.add(new Animal());
for (Object o : list) {
System.out.println(o);
}
}
}
实例二:
/**
* @author Jason
* @create 2020-07-12 9:23
* 下限通配符
*/
public class Test05 {
public static void main(String[] args) {
//这里的TreeSet底层采用的是下限通配符:public TreeSet(Comparator super E> comparator)
//我们在构造子类对象的时候,必须先构造父类对象,如果这时候比较的是父类成员的话是没有任何问题的。
//而如果这里比较子类对象的话,则不可以,因为它还没有构造出来
//TreeSet treeSet = new TreeSet<>(new Comparator2());
TreeSet treeSet = new TreeSet<>(new Comparator1());
treeSet.add(new Cat("jack", 10));
treeSet.add(new Cat("mimi", 14));
treeSet.add(new Cat("jim", 11));
treeSet.add(new Cat("bibi", 16));
treeSet.add(new Cat("didi", 6));
for (Cat cat : treeSet) {
System.out.println(cat);
}
}
}
class Comparator1 implements java.util.Comparator {
@Override
public int compare(Animal o1, Animal o2) {
return o1.name.compareTo(o2.name);
}
}
class Comparator2 implements Comparator {
@Override
public int compare(Cat o1, Cat o2) {
return o1.age-o2.age;
}
}
class Comparator3 implements Comparator {
@Override
public int compare(MiniCat o1, MiniCat o2) {
return o1.level-o2.level;
}
}
/**
* @author Jason
* @create 2020-07-12 10:00
*/
public class Test06 {
public static void main(String[] args) {
ArrayList intList = new ArrayList<>();
ArrayList strList = new ArrayList<>();
System.out.println(intList.getClass().getSimpleName());
System.out.println(strList.getClass().getSimpleName());
System.out.println("=============");
System.out.println(intList.getClass() == strList.getClass());
}
}
控制台输出:
ArrayList
ArrayList
=============
true
3、无限制类型擦除
/**
* @author Jason
* @create 2020-07-12 10:05
*/
public class Erasure {
private T key;
public T getKey() {
return key;
}
public void setKey(T key) {
this.key = key;
}
}
/**
* @author Jason
* @create 2020-07-12 10:05
*/
public class Erasure {
private Object key;
public Object getKey() {
return key;
}
public void setKey(Object key) {
this.key = key;
}
}
4、有限制类型擦除
/**
* @author Jason
* @create 2020-07-12 10:05
*/
public class Erasure {
private T key;
public T getKey() {
return key;
}
public void setKey(T key) {
this.key = key;
}
}
/**
* @author Jason
* @create 2020-07-12 10:05
*/
public class Erasure {
private Number key;
public Number getKey() {
return key;
}
public void setKey(Number key) {
this.key = key;
}
}
5、擦除方法中定义的参数
public T getValue(T value) {
return t;
}
public Number getValue(Number value) {
return value;
}
6、桥接方法
/**
* @author Jason
* @create 2020-07-12 10:31
* 泛型接口
*/
public interface Info {
T info(T t);
}
public class InfoImpl implements Info {
@Override
public Integer info(Integer integer) {
return null;
}
}
/**
* @author Jason
* @create 2020-07-12 10:31
* 泛型接口
*/
public interface Info {
Object info(Object var);
}
public class InfoImpl implements Info {
public Integer info(Integer var) {
return null;
}
@Override
public Object info(Object var) {
return info((Integer) var);
}
}
/**
* @author Jason
* @create 2020-07-12 10:53
* 泛型与数组
*/
public class demo07 {
public static void main(String[] args) {
//不能直接创建带泛型的数组对象
//ArrayList[] listArr = new ArrayList<>();
ArrayList[] listArr = new ArrayList[5];
ArrayList intList = new ArrayList<>();
intList.add(100);
ArrayList strList = new ArrayList<>();
strList.add("jason");
listArr[0] = strList;
String s = listArr[0].get(0);
System.out.println(s);
}
}
/**
* @author Jason
* @create 2020-07-12 11:07
*/
public class Fruit {
private T[] array;
public Fruit(Class clz, int length) {
array = (T[])Array.newInstance(clz, length);
}
public void put(int index, T item) {
array[index]=item;
}
public T get(int index) {
return array[index];
}
public T[] getArray(){
return array;
}
}
/**
* @author Jason
* @create 2020-07-12 10:53
* 泛型与数组
*/
public class Test07 {
public static void main(String[] args) {
Fruit fruit = new Fruit<>(String.class, 3);
fruit.put(0, "桃子");
fruit.put(1, "栗子");
fruit.put(2, "苹果");
System.out.println(Arrays.toString(fruit.getArray()));
String s1 = fruit.get(2);
System.out.println(s1);
}
}
/**
* @author Jason
* @create 2020-07-12 11:19
*/
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
/**
* @author Jason
* @create 2020-07-12 11:20
*/
public class Test08 {
public static void main(String[] args) throws Exception {
//使用泛型
Class personClass = Person.class;
Constructor constructor = personClass.getConstructor();
Person person = constructor.newInstance();
//不使用泛型创建对象的时候是object类型的,后续还需要进行数据类型的转化
Class personClass1 =Person.class;
Constructor constructor1 = personClass1.getConstructor();
Object o = constructor1.newInstance();
}
}