16.Set、泛型、枚举、反射、Class

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;
    }

    @Override
    public String toString() {
        return "Student{" +
        "sid=" + sid +
        ", name='" + name + '\'' +
        ", className='" + className + '\'' +
        '}';
    }

    @Override
    public 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;
    }

    @Override
    public int hashCode() {
        int result = sid;
        result = 31 * result + (name != null ? name.hashCode() : 0);
        result = 31 * result + (className != null ? className.hashCode() : 0);
        return result;
    }

    @Override
    public 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) {
        //创建一个没有泛型的ObjectTool
        ObjectTool 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);
    }

    @Override
    public 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);//true
        System.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();
        //获取到类加载器Classloader
        InputStream 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;
    }
}
  • 36
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值