Set
Set集合是Collection集合的子接口,元素不能重复,只能有一个null,元素存放无序。
常用子类
HashSet
TreeSet
LinkedHashSet
HashSet
其实底层就是HashMap,当我们构造一个HashSet对象,就是在 new HashSet();
当我们往HashSet中存放元素,其实在通过map调用Map的put方法,把Set添加的元素作为Map的键, 值默认存放一个空对象。
所有的方法,都是通过底层的HashMap调用了HashMap中的方法。
特点:存放元素是无序的、可以存放null、元素不能重复、线程不安全。
package com.day16.set;import java.util.HashSet;
import java.util.Iterator;public class HashSetDemo {public static void main(String[] args) {//创建HashSet对象HashSet<String> hashSet = new HashSet<>();hashSet.add("hello");hashSet.add("world");hashSet.add("java");hashSet.add("hello");for (String s : hashSet) {System.out.println(s);}Iterator<String> iterator = hashSet.iterator();while (iterator.hasNext()){System.out.println(iterator.next());}}
}
package com.day16.set;public class Student implements Comparable{private int sid;private String name;private String className;public Student(int sid, String name, String className) {this.sid = sid;this.name = name;this.className = className;}public Student() {}public int getSid() {return sid;}public void setSid(int sid) {this.sid = sid;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getClassName() {return className;}public void setClassName(String className) {this.className = className;}@Overridepublic String toString() {return "Student{" +"sid=" + sid +", name='" + name + '\'' +", className='" + className + '\'' +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;if (sid != student.sid) return false;if (name != null ? !name.equals(student.name) : student.name != null) return false;return className != null ? className.equals(student.className) : student.className == null;}@Overridepublic int hashCode() {int result = sid;result = 31 * result + (name != null ? name.hashCode() : 0);result = 31 * result + (className != null ? className.hashCode() : 0);return result;}@Overridepublic int compareTo(Object o) {Student s = (Student) o;if (this.getSid()>s.getSid()){return 1;}else if ((this.getSid()<s.getSid())){return -1;}return 0;}
}
package com.day16.set;import java.util.HashSet;public class HashSetDemo01 {public static void main(String[] args) {Student s1 = new Student(1001, "张三", "1班");Student s2 = new Student(1002, "李四", "2班");Student s3 = new Student(1003, "王五", "1班");Student s4 = new Student(1001, "张三", "1班");Student s5 = new Student(1002, "李四", "2班");HashSet<Student> students = new HashSet<>();students.add(s1);students.add(s2);students.add(s3);students.add(s4);students.add(s5);System.out.println(students);}
}
LinkedHashSet
底层其实是LinkedHashMap,所以它也具有LinkedHashMap的特点,有序性
这里的有序指的是存放有序,底层具有双向链表的特点
所有的方法都是继承自父类的HashSet,其它的方法都参考HashSet
特点:存放元素是有序的(存取有序)、可以存放null、元素不能重复、线程不安全。
package com.day16.set;import java.util.Iterator;
import java.util.LinkedHashSet;public class LinkedHashSetDemo {public static void main(String[] args) {LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();linkedHashSet.add("hello");linkedHashSet.add("world");linkedHashSet.add("linux");linkedHashSet.add("world");System.out.println(linkedHashSet);for (String s : linkedHashSet) {System.err.println(s);}Iterator<String> iterator = linkedHashSet.iterator();while (iterator.hasNext()){System.out.println(iterator.next());}}
}
TreeSet
底层是TreeMap
特点:元素不能重复,存放的元素会实现自然排序,所以存放进来的对象必须要实现comparable接口,重写compareTo方法,不能存放null元素。
package com.day16.set;import java.util.Iterator;
import java.util.TreeSet;public class TreeSetDemo {public static void main(String[] args) {TreeSet<Object> treeSet = new TreeSet<>();treeSet.add("hello");treeSet.add("java");treeSet.add("mysql");treeSet.add("linux");treeSet.add("hello");treeSet.add("a");treeSet.add("z");System.out.println(treeSet);for (Object o : treeSet) {System.out.println(o);}Iterator<Object> iterator = treeSet.iterator();while (iterator.hasNext()){System.out.println(iterator.next());}}
}
package com.day16.set;import java.util.Comparator;
import java.util.TreeSet;public class TreeSetDemo01 {public static void main(String[] args) {//存入学生对象,按照学号自然排序Student s1 = new Student(1003, "张三", "1班");Student s2 = new Student(1002, "李四", "2班");Student s3 = new Student(1005, "王五", "1班");Student s4 = new Student(1004, "jack", "1班");Student s5 = new Student(1001, "tom", "2班");// TreeSet<Student> treeSet = new TreeSet<>(new Comparator<Student>() {// @Override// public int compare(Student o1, Student o2) {// if (o1.getSid() > o2.getSid()) {// return 1;// } else if (o1.getSid() < o2.getSid()) {// return -1;// }// return 0;// }// });TreeSet<Student> treeSet = new TreeSet<>();treeSet.add(s1);treeSet.add(s2);treeSet.add(s3);treeSet.add(s4);treeSet.add(s5);System.out.println(treeSet);}
}
练习:写个方法,可以生成1-20之间的不重复的10个随机数,生成之后给他们做排序
package com.day16.prac;import java.util.Comparator;
import java.util.Random;
import java.util.TreeSet;/*
写个方法,可以生成1-20之间的不重复的10个随机数
生成之后给他们做排序*/
public class Demo {public static void main(String[] args) {TreeSet<Integer> treeSet = new TreeSet<>();while (treeSet.size() <10) {Random random = new Random();int i = random.nextInt(20) + 1;treeSet.add(i);}System.out.println(treeSet);}
}
Collections工具类
package com.day16.set2;import java.util.ArrayList;
import java.util.Collections;public class ArrayListDemo {public static void main(String[] args) {//往集合中,存放元素,然后将集合的元素翻转后输出ArrayList<Integer> arrayList = new ArrayList<>();arrayList.add(1);arrayList.add(2);arrayList.add(3);arrayList.add(4);arrayList.add(5);arrayList.add(6);arrayList.add(7);System.out.println(arrayList);
// ArrayList<Integer> list = new ArrayList<>();
// for (int i = arrayList.size()-1; i >=0 ; i--) {
// list.add(arrayList.get(i));
// }
//
// System.out.println(list);Collections.reverse(arrayList); //翻转方法System.out.println(arrayList);Collections.sort(arrayList); //给list排序System.out.println(arrayList);}}
泛型
概念
在集合中,可以往集合中存放明确的数据类型的对象,这个时候,就需要在创建集合的时候,
就指定这个集合可以存放哪个具体的类型。
在创建集合对象的时候,可以在集合的后面,把类型当作参数的形式传入到集合中,
比如List<String>这种写法,可以看作是将String这个数据类型,以参数的形式传入List集合中,
将来这个List集合中就只能存放String类型的数据
这种写法,就称为泛型。泛型本质上就是将数据类型参数化,将来自己可以类、接口、方法上面指定一个泛型,从而保证将来方法、类使用的广泛性。
格式:<数据类型>
好处:
1.避免强制类型转换,如果不指定,将来获取的都是Object
2.优化了程序
3.把运行期间的问题,提前到了编译期间
泛型用在哪些地方?
在类、接口后面看到<E> <T> ,就表示要使用泛型,一般都是在集合中。
ArrayList<String> arrayList = new ArrayList<>();
package com.day16.fanxing;public interface Inter<T> {void show(T t);
}
自己定义泛型的使用
package com.day16.fanxing;public class ObjectTool<E> {private E obj;public E getObj() {return obj;}public void setObj(E obj) {this.obj = obj;}
}
package com.day16.fanxing;public class TestObjectTool {public static void main(String[] args) {//创建一个没有泛型的ObjectToolObjectTool tool = new ObjectTool();tool.setObj("java");Object obj = tool.getObj();System.out.println(obj);//指定泛型ObjectTool<Integer> tool1 = new ObjectTool<>();tool1.setObj(10);Integer i1 = tool1.getObj();System.out.println(i1);}
}
package com.day16.fanxing;public class ObjectTool1 {public <T> void show(T t){System.out.println(t);}public static void main(String[] args) {ObjectTool1 tool1 = new ObjectTool1();tool1.show("hello");tool1.show(100);tool1.show(true);// ObjetTool1<String> tool2 = new ObjetTool1<>();}
}
泛型的通配符
? 任意类型,都可以使用
? extends E 向下限定,E 和它的子类
? super E 向上限定,E和它的父类
package com.day16.fanxing;public class Animal {
}
package com.day16.fanxing;public class Cat extends Animal{
}
package com.day16.fanxing;public class Dog extends Animal{
}
package com.day16.fanxing;import java.util.ArrayList;
import java.util.Collection;public class AnimalDemo {public static void main(String[] args) {//泛型的通配符的使用// ?Collection<Object> c1 = new ArrayList<Object>();// Collection<Object> c2 = new ArrayList<Animal>();// Collection<Object> c3 = new ArrayList<Dog>();// Collection<Object> c4 = new ArrayList<Cat>();Collection<?> c5 = new ArrayList<Object>();Collection<?> c6 = new ArrayList<Animal>();Collection<?> c7 = new ArrayList<Dog>();Collection<?> c8 = new ArrayList<Cat>();//Collection<? extends Animal> c15 = new ArrayList<Object>();Collection<? extends Animal> c16 = new ArrayList<Animal>();Collection<? extends Animal> c17 = new ArrayList<Dog>();Collection<? extends Animal> c18 = new ArrayList<Cat>();Collection<? super Animal> c15 = new ArrayList<Object>();Collection<? super Animal> c26 = new ArrayList<Animal>();// Collection<? super Animal> c27 = new ArrayList<Dog>();// Collection<? super Animal> c28 = new ArrayList<Cat>();}
}
枚举 Enum
枚举类,是和Java中的类一个级别的类型
将来定义的每一个枚举类,都是继承自java.lang.Enum类,
每个枚举类型的成员都可以看成是Enum类的实例,这些枚举成员默认是final public static修饰的
当需要使用成员的时候,直接通过枚举名称调用就行了。
package com.day16.Enum1;public enum Color {RED,BLUE,WHITE,YELLOW;//就是Color的实例对象
}
所有的枚举实例,都可以调用Enum中的方法
values()
T valueOf(类<T> enumType, String name) 返回具有指定名称的指定枚举类型的枚举常量。
int ordinal() 返回此枚举常数的序数(其枚举声明中的位置,其中初始常数的序数为零)。
package com.day16.Enum1;import java.util.Arrays;public class TestEnum {public static void main(String[] args) {System.out.println(Arrays.toString(Color.values()));for (int i = 0; i <Color.values().length ; i++) {System.out.println(Color.values()[i]);}String color="红色";switch (color){case "红色":System.out.println("红色执行的内容");break;case "蓝色":System.out.println("蓝色执行的内容");break;case "黄色":System.out.println("黄色执行的内容");break;}}
}
反射:框架设计的灵魂
框架:半成品软件,可以极大地简化代码编写。
程序的编译期和运行期
编译期:将源代码交给编译器去编译成计算机可以执行的文件的过程。
在Java中,就是把.Java文件编译成.class文件的过程。
编译可以看作是翻译,这个期间,并没有把代码放入内存中运行起来,
只会把代码当作文件进行操作,比如检查是否存在错误。
运行期:将编译后的文件交给计算机执行,直到程序执行结束。
其实就是把磁盘中的代码放到内存中去执行。
Java反射机制
在程序运行状态下,对于任意一个类,都可以去获取这个类的所有属性和方法,
对于任意一个对象,都能够调用它的任意属性和方法。
(以上的操作,并不是像以前学习的面向对象一样,在创建对象之后,而是在没有创建对象的情况下获取的)
这种动态获取信息以及动态调用对象方法的功能,称为Java反射机制。
简单说,反射机制就是指,程序运行时,能够获取自身的信息。
在Java中,只要知道类的名字,就能够获取这个类的所有信息。
Java中,声明每个类都是class类的类对象。
通过class类的方法可以去获取到每个类的属性、方法,并且可以在没有new对象的情况下,去执行这些属性、方法。
Java代码在计算机中执行的三个阶段
1.source源代码阶段:这个阶段代码放在硬盘,没进内存
2.class类对象阶段
3.runtime运行阶段
之前需要执行代码,是从阶段1,只能接通过new 进入到阶段3的runtime,
反射就是研究在class类对象阶段,获取类的属性、方法,并执行。
获取Class类对象的方式
1.第一阶段还没加载的时候,通过要获取类的全类名去获取类对象 【Class.forName("全类名");】
将来配置文件的时候,可以将类名配置在配置文件中,通过读取配置文件,加载类
Class<?> personClass =
Class.forName("com.day16.reflect.Person");
2.加载进内存,还没实例化,通过【类名.class】获取这个类的Class类对象
常用于参数的传递
Class<Person> personClass1 = Person.class;
3.实例化对象后,通过对象,也能获取到这个类的类对象 【对象.getClass()方法】
一般用于对象获取字节码的方式
Class personClass2 = new Person().getClass();
package com.day16.reflect;public class Person {String name;int age;private String a;String b;protected String c;public String d;public Person(String name, int age) {this.name = name;this.age = age;}public Person() {}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public void eat(){System.out.println("eat....");}public void eat(String food){System.out.println("eat"+food);}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", a='" + a + '\'' +", b='" + b + '\'' +", c='" + c + '\'' +", d='" + d + '\'' +'}';}
}
package com.day16.reflect;import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;public class ReflectDemo {public static void main(String[] args) throws Exception {//1.第一阶段还没加载的时候,通过要获取类的全类名去获取类对象//Class.forName("全类名");//将来配置文件的时候,可以将类名配置在配置文件中,通过读取配置文件,加载类Class<?> personClass =Class.forName("com.day16.reflect.Person");//2.加载进内存,还没实例化//通过类名.class获取这个类的Class类对象//常用于参数的传递Class<Person> personClass1 = Person.class;//3.实例化对象后,通过对象,也能获取到这个类的类对象//对象.getClass()方法//一般用于对象获取字节码的方式Class personClass2 = new Person().getClass();System.out.println(personClass==personClass1);//trueSystem.out.println(personClass1==personClass2);//true//返回类名String name = personClass.getName();System.out.println(name);//获取类对象属性//Field getField(String name) 获取指定名称的成员属性Field d = personClass.getField("d");System.out.println(d);//Field[] getFields() 获取类对象中所有可以访问的属性Field[] fields = personClass.getFields();for (Field field1 : fields) {System.out.println(field1);}System.out.println("--------------------------");//Field getDeclaredField(String name) 返回一个指定的私有化的成员属性Field name1 = personClass.getDeclaredField("name");System.out.println(name1);Field a = personClass.getDeclaredField("a");System.out.println(a);//Field[] getDeclaredFields() 返回所有的私有化的成员属性Field[] declaredFields = personClass.getDeclaredFields();for (Field declaredField : declaredFields) {System.out.println(declaredField);}//获取类对象构造方法,存入参数的Class类对象System.out.println("==============构造方法=================");//Constructor<T> getConstructor(类<?>... parameterTypes)//返回一个 Constructor对象,该对象反映 Constructor对象表示的类的指定的公共 类函数。Constructor<?> constructor2 = personClass.getConstructor();System.out.println(constructor2);System.out.println("-----------------");Constructor<?> constructor1 =personClass.getConstructor(String.class, int.class);System.out.println(constructor1);System.out.println("--------------------------");//Constructor<?>[] getConstructors()//返回包含一个数组 Constructor对象反射由此表示的类的所有公共构造 类对象。Constructor<?>[] constructors = personClass.getConstructors();for (Constructor<?> constructor : constructors) {System.out.println(constructor);}//T newInstance()//创建由此 类对象表示的类的新实例。Person p = (Person) constructor2.newInstance();p.eat();Person p1 = (Person) constructor1.newInstance("jack", 20);System.out.println(p1.getName());//也可以通过类对象直接调用newInstance()类创建对象//这里其实就是在调用Person的无参构造来创建对象Person p2 = (Person) personClass.newInstance();p2.eat();//使用Field对象去给属性赋值//void set(Object obj, Object value)//将指定对象参数上的此 Field对象表示的字段设置为指定的新值。d.set(p2,"hello");System.out.println(p2);name1.set(p2,"tom");System.out.println(p2);a.setAccessible(true);//暴力反射,可以使私有化属性赋值a.set(p2,"world");System.out.println(p2);//获取对象的普通方法System.out.println("=============普通方法===============");//方法 getMethod(String name, 类<?>... parameterTypes)//返回一个 方法对象,它反映此表示的类或接口的指定公共成员方法 类对象。//方法[] getMethods()//返回包含一个方法对象数组,包括所有方法//方法 getDeclaredMethod(String name, 类<?>... parameterTypes)//返回一个 方法对象,它反映此表示的类或接口的指定声明的方法 类对象。//方法[] getDeclaredMethods()//返回包含一个数组 方法对象反射的类或接口的所有声明的方法,通过此表示 类对象,包括公共,保护,默认(包)访问和私有方法,但不包括继承的方法。//所有Method[] methods = personClass.getMethods();for (Method method : methods) {System.out.println(method);}//单个System.out.println("---------------------");Method method1 = personClass.getMethod("eat");System.out.println(method1);Method method2 = personClass.getMethod("eat", String.class);System.out.println(method2);//Method对象中,有invoke方法,可以通过调用这个方法,执行指定的方法,//Object invoke(Object obj, Object... args)//在具有指定参数的 方法对象上调用此 方法对象表示的底层方法。method1.invoke(p2);method2.invoke(p2,"冰激凌");}
}
Class类对象的方法
获取类对象构造方法
Constructor<T> getConstructor(类<?>... parameterTypes)
返回一个 Constructor对象,该对象反映 Constructor对象表示的类的指定的公共 类函数。
Constructor<?>[] getConstructors()
返回包含一个数组 Constructor对象反射由此表示的类的所有公共构造 类对象。
获取对象的普通方法
方法 getMethod(String name, 类<?>... parameterTypes)
返回一个 方法对象,它反映此表示的类或接口的指定公共成员方法 类对象。
方法[] getMethods()
返回包含一个方法对象数组,包括所有方法
方法 getDeclaredMethod(String name, 类<?>... parameterTypes)
返回一个 方法对象,它反映此表示的类或接口的指定声明的方法 类对象。
方法[] getDeclaredMethods()
返回包含一个数组 方法对象反射的类或接口的所有声明的方法,通过此表示 类对象,包括公共,保护,默认(包)访问和私有方法,但不包括继承的方法。
Method对象中,有invoke方法,可以通过调用这个方法,执行指定的方法,
Object invoke(Object obj, Object... args)
在具有指定参数的 方法对象上调用此 方法对象表示的底层方法。
method1.invoke(p2);
method2.invoke(p2,"冰激凌");
package com.day16.reflect;import java.lang.reflect.Constructor;
import java.lang.reflect.Method;public class ReflectDemo01 {public static void main(String[] args) throws Exception {//通过要获取类的全类名去获取类对象Class<?> personClass =Class.forName("com.day16.reflect.Person");//获取类对象构造方法,存入参数的Class类对象System.out.println("==============构造方法=================");//Constructor<T> getConstructor(类<?>... parameterTypes)//返回一个 Constructor对象,该对象反映 Constructor对象表示的类的指定的公共 类函数。Constructor<?> constructor2 = personClass.getConstructor();System.out.println(constructor2);System.out.println("-----------------");Constructor<?> constructor1 =personClass.getConstructor(String.class, int.class);System.out.println(constructor1);System.out.println("--------------------------");//Constructor<?>[] getConstructors()//返回包含一个数组 Constructor对象反射由此表示的类的所有公共构造 类对象。Constructor<?>[] constructors = personClass.getConstructors();for (Constructor<?> constructor : constructors) {System.out.println(constructor);}//T newInstance()//创建由此 类对象表示的类的新实例。Person p = (Person) constructor2.newInstance();p.eat();Person p1 = (Person) constructor1.newInstance("jack", 20);System.out.println(p1.getName());//也可以通过类对象直接调用newInstance()类创建对象//这里其实就是在调用Person的无参构造来创建对象Person p2 = (Person) personClass.newInstance();p2.eat();//获取对象的普通方法System.out.println("=============普通方法===============");//方法 getMethod(String name, 类<?>... parameterTypes)//返回一个 方法对象,它反映此表示的类或接口的指定公共成员方法 类对象。//方法[] getMethods()//返回包含一个方法对象数组,包括所有方法//方法 getDeclaredMethod(String name, 类<?>... parameterTypes)//返回一个 方法对象,它反映此表示的类或接口的指定声明的方法 类对象。//方法[] getDeclaredMethods()//返回包含一个数组 方法对象反射的类或接口的所有声明的方法,通过此表示 类对象,包括公共,保护,默认(包)访问和私有方法,但不包括继承的方法。//所有Method[] methods = personClass.getMethods();for (Method method : methods) {System.out.println(method);}//单个System.out.println("---------------------");Method method1 = personClass.getMethod("eat");System.out.println(method1);Method method2 = personClass.getMethod("eat", String.class);System.out.println(method2);//Method对象中,有invoke方法,可以通过调用这个方法,执行指定的方法,//Object invoke(Object obj, Object... args)//在具有指定参数的 方法对象上调用此 方法对象表示的底层方法。method1.invoke(p2);method2.invoke(p2,"冰激凌");}
}
Class类对象的功能总结
1.获取Class类对象,可以通过以上3种方式
Class<Person> personClass = Person.class;
2.获取到类对象之后可以做什么 ?
(1)可以通过类对象,直接调用newInstance()方法,创建这个类的实例对象
Person p2 = (Person) personClass.newInstance();
(2)也可以通过类对象,调用getConstructor(Class<?>... parameterTypes)
这个方法,返回 Constructor对象后,再调用newInstance(),根据参数创建这个
类的对象。
3.可以通过方法,获取所有 类的属性,包括私有的
Field getDeclaredField(String name)
Field name = personClass.getDeclaredField("name");
获取之后的返回值类型是Field,Field类型是所有类属性抽取的类, 然后可以使用Field类中的方法,去给属性赋值,赋值的时候还是要结合要被赋值的具体对象, 可以使用上面创建的对象。
如果属性是私有的,赋值之前需要加上暴力反射。
void set(Object obj, Object value)
a.setAccessible(true);//暴力反射,可以使私有化属性赋值
a.set(p2,"world");
4.可以通过方法,获取到类的所有成员方法,包括私有的
Method getMethod(String name, 类<?>... parameterTypes)
Method method2 = personClass.getMethod("eat", String.class);
获取到Method对象之后,可以通过Method对象中的方法,结合对象执行具体的某个方法
Object invoke(Object obj, Object... args)
method2.invoke(p2,"饭");
设计一个框架,实现,在不改变任何代码的情况下,可以帮助我们创建任意类的对象,并且可以执行其中任意的方法
className=com.day16.kuangjia.Student;
methodName=study;
package com.day16.kuangjia;public class Person {public void eat(){System.out.println("eat...");}
}
package com.day16.kuangjia;public class Student {public void study(){System.out.println("study...");}
}
package com.day16.kuangjia;
//设计一个框架,实现,在不改变任何代码的情况下,可以帮助我们创建任意类的对象,
//并且可以执行其中任意的方法
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;public class Test {public static void main(String[] args) throws Exception {//1、需要想办法获取到要执行的类的名称和它类中的方法//通过将类名、方法名配置在配置文件中,然后获取//在src目录下,创建一个pro.properties//并且把要访问的类的名称和方法,配置好//className=com.day16.kuangjia.Student;//methodName=study;Properties properties = new Properties();//获取到类加载器ClassloaderInputStream is = Test.class.getClassLoader().getResourceAsStream("pro.properties");properties.load(is);//2、加载配置文件,读取到配置文件中类名和方法名String className = properties.getProperty("className");String methodName = properties.getProperty("methodName");//3.通过类名获取到类对象,获取方法对象,创建对象Class<?> cls = Class.forName(className);Object o = cls.newInstance();Method method = cls.getMethod(methodName);//4、执行方法method.invoke(o);}
}
结合泛型写一个方法,将来可以根据传入的SQL语句,查询任意类的对象后,放入到list集合中,并且将这个List集合返回
package com.day16.kuangjia;import java.util.ArrayList;
import java.util.List;public class Test1 {//结合泛型写一个方法,将来可以根据传入的SQL语句,查询任意类的对象后,//放入到list集合中,并且将这个List集合返回public List<Student> selectStudent(String sql){//ArrayList<Student> students = new ArrayList<>();//students.add();return students;}public List<Person> selectTeacher(String sql){//....ArrayList<Person> people = new ArrayList<>();// students.add()return people;}public <T> List<T> selectTeacher(Class<T> tClass,String sql){//....// tClass.newInstance();ArrayList<T> people = new ArrayList<>();// students.add()return people;}
}