java基础复习——day18(反射)

反射

1. 反射取构造方法并使用

  • Constructor<?> [] getConstructors():返回所有公共构造方法对象的数组

  • Constructor<?> [] getDeclaredConstructors(): 返回所有构造方法对象的数组

  • Constructor< T> getConstructor(Class<?>… parameterTypes):返回单个公共构造方法对象

  • Constructor< T> getDeclaredConstructor(Class<?>…parameterTypes):返回单个构造方法对象

Constructor类中用于创建对象的方法:

  • newInstance: 根据指定的构造方法创建对象

暴力反射:也要会

案例:

package Lambda;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

//测试类
public class Demo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //获取Class对象
        Class<?> c = Class.forName("student.Student");

        //显示构造方法
        Constructor<?>[] declaredConstructors = c.getDeclaredConstructors();
        for (Constructor con : declaredConstructors) {
            System.out.println(con);
        }
        //public student.Student()
        //public student.Student(java.lang.String,int,java.lang.String)
        System.out.println("----------------");

        Constructor<?> constructor = c.getConstructor();
        Object obj = constructor.newInstance();//创建对象
        System.out.println(obj);
        //Student{name='null', age=0, school='null'}
    }
}

案例:获取有参构造方法

package Lambda;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

//测试类
public class Demo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //获取Class对象
        Class<?> c = Class.forName("student.Student");
        Constructor<?> con = c.getConstructor(String.class, int.class, String.class);//基本数据类型也可以通过.class 获取对应的class对象
        Object obj = con.newInstance("wen", 20, "常州");
        System.out.println(obj);
    }
}

案例:暴力反射, (获取私有)

package Lambda;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

//测试类
public class Demo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //获取Class对象
        Class<?> c = Class.forName("student.Student");
        Constructor<?> con = c.getDeclaredConstructor(String.class);

        //暴力反射
        con.setAccessible(true);//取消访问检查

        Object obj = con.newInstance("wen");
        System.out.println(obj);
        //Student{name='wen', age=0, school='null'}
    }
}

2. 反射获取成员变量并使用

  • Field[] getFields() : 返回所有公共成员变量对象的数组
  • Field[] getDeclaredFields() : 返回所有成员变量对象的数组
  • Field getField(String name):返回单个公共成员变量对象
  • Field getDeclaredField(String name):返回单个成员变量对象
package Lambda;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

//测试类
public class Demo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        //Class对象
        Class<?> c = Class.forName("student.Student");
        //得到所有的成员变量
        Field[] fields = c.getDeclaredFields();
        for (Field filed :
                fields) {
            System.out.println(filed);
            //private java.lang.String student.Student.name
            //int student.Student.age
            //public java.lang.String student.Student.school
        }
        System.out.println("----------------------");
        //得到特定的成员变量
        Field nameFiled = c.getDeclaredField("name");
        System.out.println(nameFiled);
        //private java.lang.String student.Student.name
    }
}

案例练习:用到暴力反射

package student;

/* 学生类
    alt+insert 卧槽无敌的快捷键!!!

  */
public class Student {
    private String name;
    int age;
    public String school;

    public Student() {
    }

    public Student(String name) {
        this.name = name;
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Student(String name, int age, String school) {
        this.name = name;
        this.age = age;
        this.school = school;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getSchool() {
        return school;
    }

    public void setSchool(String school) {
        this.school = school;
    }

    public void show() {
        System.out.println("????");
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", school='" + school + '\'' +
                '}';
    }
}
package Lambda;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

//测试类
public class Demo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        //Class对象
        Class<?> c = Class.forName("student.Student");
        Constructor<?> con = c.getConstructor();
        Object obj = con.newInstance();

        //赋值
        Field name = c.getDeclaredField("name");
        name.setAccessible(true);//IllegalAccessException 的 报错解决方案:暴力反射
        name.set(obj, "wts");

        Field age = c.getDeclaredField("age");
        age.setAccessible(true);//
        age.set(obj, 20);
        
        Field school = c.getDeclaredField("school");
        school.set(obj, "cczu");
        System.out.println(obj);
    }
}

3. 反射获取成员方法

Class类中用于获取成员变量的方法:

  • Method [] getMethods():返回所有公共成员方法对象的数组,包括继承的
  • Method [] getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的
  • Method getMethod(String name, Class<?>… parameterTypes):返回单个公共成员方法对象
  • Method getDeclaredMethod(String name,Class<?>… parameterTypes):返回单个成员方法对象

Method类中用于调用成员方法的方法:
.Object invoke(Object obj, Object…args):调用obj对象的成员方法,参数是args,返回值是Object类型

package Lambda;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

//测试类
public class Demo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        //Class对象
        Class<?> c = Class.forName("student.Student");

        //返回所有公共成员发放对象的数组,包括继承
        Method[] methods = c.getMethods();
        for (Method method :
                methods) {
            System.out.println(method);
        }
        System.out.println("-----------------------");

        //不包括继承
        Method[] declaredMethods = c.getDeclaredMethods();
        for (Method method :
                declaredMethods) {
            System.out.println(method);
        }
        System.out.println("-----------------------");

        //方法调用
        //创建对象
        Constructor<?> con = c.getConstructor();
        Object obj = con.newInstance();

        Method m1 = c.getDeclaredMethod("method1");
        m1.invoke(obj);//method1
    }
}

案例:

package student;

/* 学生类
    alt+insert 卧槽无敌的快捷键!!!

  */
public class Student {
    private String name;
    int age;
    public String school;

    public Student() {
    }

    public Student(String name) {
        this.name = name;
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Student(String name, int age, String school) {
        this.name = name;
        this.age = age;
        this.school = school;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getSchool() {
        return school;
    }

    public void setSchool(String school) {
        this.school = school;
    }

    public void show() {
        System.out.println("????");
    }

    public void method1() {
        System.out.println("method1");
    }

    public void method2(String s) {
        System.out.println(s);
    }

    public String method3(String name, int age) {
        return name + "," + age;
    }

    private void function() {
        System.out.println("function");
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", school='" + school + '\'' +
                '}';
    }
}
package Lambda;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

//测试类
public class Demo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        //创建对象
        Class<?> c = Class.forName("student.Student");
        Constructor<?> con = c.getConstructor();
        Object obj = con.newInstance();

        //调用method1
        Method m1 = c.getDeclaredMethod("method1");
        m1.invoke(obj);//method1

        //调用method2 有形参
        Method m2 = c.getDeclaredMethod("method2", String.class);
        m2.invoke(obj, "wts");//wts

        //调用method3 返回值是String类型
        Method m3 = c.getDeclaredMethod("method3", String.class, int.class);
        Object m3Invoke = m3.invoke(obj, "wts", 20);
        System.out.println(m3Invoke);//wts,20

        //调用私有方法 function
        Method fun1 = c.getDeclaredMethod("function");
        fun1.setAccessible(true);//暴力
        fun1.invoke(obj);//function
    }
}

反射练习:向ArrayList< Integer >添加字符串

反射可以完成一些非同寻常的操作

package Lambda;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

//测试类
public class Demo {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //创建对象
        ArrayList<Integer> arrayList = new ArrayList<>();
        arrayList.add(10);

        Class<? extends ArrayList> arrayListClass = arrayList.getClass();
        Method add1 = arrayListClass.getMethod("add", Object.class);

        add1.invoke(arrayList, "hello");
        System.out.println(arrayList);//[10, hello]
    }
}

4. 通过配置文件运行类中的方法

反射的灵活性

在这里插入图片描述

package student;

/* 学生类 */
public class Student {
    public void study() {
        System.out.println("学生学习");
    }
}
package student;

public class Teacher {
    public void teach(){
        System.out.println("老师教书");
    }
}

配置文件txt:

className=student.Student
methodName=study

在这里插入图片描述

package Lambda;

import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

//测试类
public class Demo {
    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //加载数据
        Properties prop = new Properties();
        FileReader fileReader = new FileReader("Class.txt");
        prop.load(fileReader);
        fileReader.close();

        String className = prop.getProperty("className");
        String methodName = prop.getProperty("methodName");

        //通过反射
        Class<?> c = Class.forName(className);
        Constructor<?> con = c.getConstructor();
        Object obj = con.newInstance();

        Method method = c.getDeclaredMethod(methodName);
        method.invoke(obj);
    }
}

小结:加载数据不太熟练,反射很灵活,感觉像项目框架

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值