package com.atguigu.javase.generic;import java.util.ArrayList;import java.util.List;import org.junit.Test;// 自定义泛型类, A只能是类类型class Person { // A在这里表示它是某种类型, 类型的形参, 在本类中就可以直接使用A这个类型. // A类型在创建对象时指定. // 如果A类型在创建对象时,并未确定的指定, 它就是Object类型, 类型不安全了 // 泛型类型隶属于对象的, 不同的对象在创建时指定的泛型类型可以不一样 private String name; private A info; public Person() { } public Person(String name, A info) { super(); this.name = name; this.info = info; } public void setInfo(A info) { this.info = info; } public A getInfo() { return info; } public void setName(String name) { this.name = name; } public String getName() { return name; } @Override public String toString() { return "Person [name=" + name + ", info=" + info + "]"; } /* 静态成员不可以使用泛型类型 public static void test(A a) { }*/ /** * 泛型方法, 方法中的泛型类型在方法的返回值之前声明 <泛型的类型参数> * 泛型方法必须在形参中指定好特定的类型, 否则泛型方法中的泛型类型永远是Object * 泛型方法中的泛型类型究竟是什么, 由实参来决定.所以是在方法的每一次调用时才能确定的. * 如果实参是null, 则无法确定泛型类型, 只能是Object类型了. * @return */ public B testB(B b) { return null; }}class A{ X x; public X getX() { return x; }}class B extends A {} // 子类在继承时并未指定X的具体类型, 所以永远是Objectclass C extends A 泛型的类型参数>{} // 子类在继承时直接写死父类的泛型类型, 在子类中X类型永远是一致,不变的class C2 extends A {}class D extends A {} // 子类在继承父类时仍然保持泛型类型的不确定性.public class GenericTest { @Test public void test6() { B b = new B(); Object x = b.getX(); C c = new C(); String x2 = c.getX(); D d = new D(); Object x3 = d.getX(); D d2 = new D (); Integer x4 = d2.getX(); String x5 = new D ().getX(); } @Test public void test5() { List list = new ArrayList (); for (int i = 0; i < 10; i++) { list.add((int)(Math.random() * 20)); } System.out.println(list); Object[] array = list.toArray(); for (Object object : array) { System.out.println(object); } System.out.println("**********************"); Integer[] array2 = list.toArray(new Integer[] {}); for (Integer integer : array2) { System.out.println(integer); } } @Test public void test4() { Person person = new Person ("张三", "北京"); Integer testB = person.testB(30); String testB2 = person.testB("男"); Boolean testB3 = person.testB(false); Object testB4 = person.testB(null); // 当实参的类型无法确定时, 泛型方法中的类型就是Object } @Test public void test3() { List list1 = new ArrayList (); List list2 = new ArrayList (); } @Test public void test2() { // 在这个对象中的A类型就固定是String类型 Person person = new Person ("张三", "北京"); // String在创建对象时,会作为类中的A类型的具体类型 String info = person.getInfo(); System.out.println(info); //person.setInfo(30); //new Person ("李四", "上海"); Person person2 = new Person ("李四", 40); Integer info2 = person2.getInfo(); System.out.println(info2); } @Test public void test1() { Person person = new Person("张三", 30); // 理论上A类型就是Integer了, 但是没有指定 Object info = person.getInfo(); System.out.println(info); person.setInfo("男"); // 在这里体现了类型不安全, 因为理论上类型是Integer,但是实际给定的是String Person person2 = new Person("李四", "女"); Object info2 = person2.getInfo(); System.out.println(info2); }}
静态方法不能使用泛型,因为静态方法隶属于类,而泛型是绑定到对象上的
对于更精确的类型确定,可以使用泛型方法