java反射

2024-01-08 10:26:06

反射

参考文章:反射讲解最好的文章

反射–获取Class对象的三种方式

三种方式以及特点
方式一:类名.class最方便的方式
方式二:Class.forName()最灵活的方式(类的路径)
方式三:new 类名.getClass()最无奈的方式

demo:

定义一个学生类(Student)

package com.itxs.demo01;

/**
 * @Classname : Student
 * @Description : TODO 学生类
 * @Author : lin_refuel@qq.com
 */
public class Student {
}

三种获取Class方式的验证

package com.itxs.demo01;

/**
 * @Classname : demo01
 * @Description : TODO 反射 - 获取Class对象的方式
 * @Author : lin_refuel@qq.com
 */
public class demo01 {
    public static void main(String[] args) throws ClassNotFoundException {
         //方式一:类名.class
        Class<Student> c01 = Student.class;
        System.out.println(c01);//最方便的方式
        //方式二:
        Class<? extends Student> c02 = new Student().getClass();//无奈的方式
        System.out.println(c02);
        //方式三
        Class<?> c03 = Class.forName("com.itxs.demo01.Student");//最灵活的方式
        System.out.println(c03);
    }
}

运行结果:Student类的路径
在这里插入图片描述

反射构造方法的获取

Class获取构造方法四个方法概述

四个方法作用
getConstructor()获取公有的无参的构造方法,也可进行传递参数获取指定公有构造方法
getConstructors()获取到类中所有公有构造方法,形成一个数组
getDeclaredConstructor()可以根据参数获取一个指定的构造方法,公有和私有,等类型不限制,没有参数,默认为是无参构造方法
getDeclaredConstructors()获取类中所有的构造方法,形成一个数组,

测试上面的四个方法

demo:

Student类,包含一些公有,私有,受保护的成员属性,构造方法,成员方法等

package com.itxs.demo01;

/**
 * @Classname : Student
 * @Description : TODO 学生类
 * @Author : lin_refuel@qq.com
 */
public class Student {
    //定义出学生的属性
    //两个公有属性
    public String name; //姓名
    public int age; // 年龄
    //两个私有属性
    private float score;//成绩
    private int sex;//性别
    //两个受保护的属性
    protected String interest;
    protected int ranking;
    // 一个默认的
    int classid;

    // 默认的无参构造方法
     public Student() {
    }
    // 两个公有的构造方法

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

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    // 两个私有的构造方法

    private Student(String name, int age, float score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    private Student(String name, int age, float score, int sex) {
        this.name = name;
        this.age = age;
        this.score = score;
        this.sex = sex;
    }
    //两个受保护的构造方法

    protected Student(String name, int age, float score, int sex, String interest) {
        this.name = name;
        this.age = age;
        this.score = score;
        this.sex = sex;
        this.interest = interest;
    }

    protected Student(String name, int age, float score, int sex, String interest, int ranking, int classid) {
        this.name = name;
        this.age = age;
        this.score = score;
        this.sex = sex;
        this.interest = interest;
        this.ranking = ranking;
        this.classid = classid;
    }
    //成员变量的get和set

    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 float getScore() {
        return score;
    }

    public void setScore(float score) {
        this.score = score;
    }

    public int getSex() {
        return sex;
    }

    public void setSex(int sex) {
        this.sex = sex;
    }

    public String getInterest() {
        return interest;
    }

    public void setInterest(String interest) {
        this.interest = interest;
    }

    public int getRanking() {
        return ranking;
    }

    public void setRanking(int ranking) {
        this.ranking = ranking;
    }

    public int getClassid() {
        return classid;
    }

    public void setClassid(int classid) {
        this.classid = classid;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                ", sex=" + sex +
                ", interest='" + interest + '\'' +
                ", ranking=" + ranking +
                ", classid=" + classid +
                '}';
    }
    //*****************************************
    //两个公有方法
    public void monPu(){
        System.out.println("我是无参公有方法");
    }
    public void monPu(String args){
        System.out.println("我是带参公有方法,参数"+args);
    }
    private void monPri(){
        System.out.println("我是无参私有方法");
    }
    private void monPri(String args){
        System.out.println("我是带参私有方法,参数"+args);
    }
    protected void monPro(){
        System.out.println("我是受保护的无参方法");
    }
    protected void monPro(String args){
        System.out.println("我是受保护带参方法,参数"+args);
    }
}

getConstructor()

package com.itxs.demo01;

import java.lang.reflect.Constructor;

/**
 * @Classname : demo02
 * @Description : TODO 反射 - 构造方法的获取
 * @Author : lin_refuel@qq.com
 */
public class demo02 {
    public static void main(String[] args) throws NoSuchMethodException {
         // 获取一个Class对象,类名.class
        Class<Student> stu01 = Student.class;
         // 获取类公有无参的构造方法
        Constructor<Student> c01 = stu01.getConstructor();
        System.out.println(c01);//public com.itxs.demo01.Student()
    }
}

运行结果:
在这里插入图片描述

getConstructors()

package com.itxs.demo01;

import java.lang.reflect.Constructor;

/**
 * @Classname : demo02
 * @Description : TODO 反射 - 构造方法的获取
 * @Author : lin_refuel@qq.com
 */
public class demo02 {
    public static void main(String[] args) throws NoSuchMethodException {
         // 获取一个Class对象,类名.class
        Class<Student> stu01 = Student.class;
         // 获取类中所有的公有构造方法,形成一个数组
        Constructor<?>[] c01 = stu01.getConstructors();
        //对数组进行遍历
        for (Constructor<?> c1 : c01) {
            System.out.println(c1);
        }
    }
}

运行结果:
在这里插入图片描述

getDeclaredConstructor()

package com.itxs.demo01;

import java.lang.reflect.Constructor;

/**
 * @Classname : demo02
 * @Description : TODO 反射 - 构造方法的获取
 * @Author : lin_refuel@qq.com
 */
public class demo02 {
    public static void main(String[] args) throws NoSuchMethodException {
         // 获取一个Class对象,类名.class
        Class<Student> stu01 = Student.class;
         // 获取类中指定的构造方法,或者不传参数获取默认方法
        Constructor<Student> s01 = stu01.getDeclaredConstructor();
        System.out.println("默认无参构造方法" + s01);
        System.out.println("==========================");
        // 获取 四个参数的私有构造方法
        Constructor<Student> s02 = stu01.getDeclaredConstructor(String.class, int.class, float.class, int.class);
        System.out.println("私有且带有四个参数的构造方法"+ s02);
    }
}

运行结果:
在这里插入图片描述

getDeclaredConstructors()

package com.itxs.demo01;

import java.lang.reflect.Constructor;

/**
 * @Classname : demo02
 * @Description : TODO 反射 - 构造方法的获取
 * @Author : lin_refuel@qq.com
 */
public class demo02 {
    public static void main(String[] args) throws NoSuchMethodException {
         // 获取一个Class对象,类名.class
        Class<Student> stu01 = Student.class;
        // 获取类中全部的构造方法形成数组
        Constructor<?>[] s02 = stu01.getDeclaredConstructors();
        //进行遍历
        for (Constructor<?> s2 : s02) {
            System.out.println(s2);
        }
    }
}

运行结果:
在这里插入图片描述

获取的构造方法进行实例化输出

package com.itxs.demo01;

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

/**
 * @Classname : demo03
 * @Description : TODO
 * @Author : lin_refuel@qq.com
 */
public class demo03 {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        // 反射获取一个类
        Class<Student> stu01 = Student.class;
        // 调用方法getConstructor,获取到带一个参数类型的构造方法
        Constructor<Student> c01 = stu01.getConstructor(String.class);
        // 获取的构造方法进行实例化,调用newInstance
        Student new01 = c01.newInstance("小肆");
        // 输出构造方法
        System.out.println(new01);
    }
}

运行结果:
在这里插入图片描述

获取私有的构造方法进行实例化,输出

package com.itxs.demo01;

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

/**
 * @Classname : demo04
 * @Description : TODO 获取类中私有构造方法进行实例化,输出
 * @Author : lin_refuel@qq.com
 */
public class demo04 {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
         // 反射获取一个类
        Class<Student> Stu01 = Student.class;
         // 调用方法获取一个私有的构造方法
        Constructor<Student> get01 = Stu01.getDeclaredConstructor(String.class, int.class, float.class, int.class);
        // 关闭异常检测 true是关闭检测,false是开启异常检测
        get01.setAccessible(true);
        // 获取的私有构造方法进行实例化
        Student s = get01.newInstance("小肆", 18, 88, 1);
        System.out.println(s);
    }
}

运行结果:
在这里插入图片描述

反射–获取Class中的成员变量

定义一个学生类

package com.itxs.demo01;

/**
 * @Classname : Student
 * @Description : TODO 学生类
 * @Author : lin_refuel@qq.com
 */
public class Student {
    //定义出学生的属性
    //两个公有属性
    public String name; //姓名
    public int age; // 年龄
    //两个私有属性
    private float score;//成绩
    private int sex;//性别
    //两个受保护的属性
    protected String interest;
    protected int ranking;
    // 一个默认的
    int classid;

    // 默认的无参构造方法
     Student() {
    }
    // 两个公有的构造方法

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

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    // 两个私有的构造方法

    private Student(String name, int age, float score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    private Student(String name, int age, float score, int sex) {
        this.name = name;
        this.age = age;
        this.score = score;
        this.sex = sex;
    }
    //两个受保护的构造方法

    protected Student(String name, int age, float score, int sex, String interest) {
        this.name = name;
        this.age = age;
        this.score = score;
        this.sex = sex;
        this.interest = interest;
    }

    protected Student(String name, int age, float score, int sex, String interest, int ranking, int classid) {
        this.name = name;
        this.age = age;
        this.score = score;
        this.sex = sex;
        this.interest = interest;
        this.ranking = ranking;
        this.classid = classid;
    }
    //成员变量的get和set

    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 float getScore() {
        return score;
    }

    public void setScore(float score) {
        this.score = score;
    }

    public int getSex() {
        return sex;
    }

    public void setSex(int sex) {
           if(sex>1){
              System.out.println("性别非法,0:性别女,1性别男,默认性别男");
              sex = 1;
              System.exit(-1);//程序退出
          }
        this.sex = sex;
    }

    public String getInterest() {
        return interest;
    }

    public void setInterest(String interest) {
        this.interest = interest;
    }

    public int getRanking() {
        return ranking;
    }

    public void setRanking(int ranking) {
        this.ranking = ranking;
    }

    public int getClassid() {
        return classid;
    }

    public void setClassid(int classid) {
        this.classid = classid;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                ", sex=" + sex +
                ", interest='" + interest + '\'' +
                ", ranking=" + ranking +
                ", classid=" + classid +
                '}';
    }
    //*****************************************
    //两个公有方法
    public void monPu(){
        System.out.println("我是无参公有方法");
    }
    public void monPu(String args){
        System.out.println("我是带参公有方法,参数"+args);
    }
    private void monPri(){
        System.out.println("我是无参私有方法");
    }
    private void monPri(String args){
        System.out.println("我是带参私有方法,参数"+args);
    }
    protected void monPro(){
        System.out.println("我是受保护的无参方法");
    }
    protected void monPro(String args){
        System.out.println("我是受保护带参方法,参数"+args);
    }
}

getFields()

package com.itxs.demo01;

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

/**
 * @Classname : demo05
 * @Description : TODO 反射获取类中的成员属性,进行赋值访问
 * @Author : lin_refuel@qq.com
 */
public class demo05 {
    public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
           // 反射获取一个对象
        Class<Student> stu01 = Student.class;
          // 调用方法获取stu01中的所有公有的变量
        Field[] get01 = stu01.getFields(); // 公有变量的集合
        for (Field get001 : get01) {
            System.out.println(get001);
        }
    }
}

运行结果:
在这里插入图片描述

getField()

package com.itxs.demo01;

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

/**
 * @Classname : demo05
 * @Description : TODO 反射获取类中的成员属性,进行赋值访问
 * @Author : lin_refuel@qq.com
 */
public class demo05 {
    public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
           // 反射获取一个对象
        Class<Student> stu01 = Student.class;
          // 调用方法getField(),可以获取指定成员变量
        Field age = stu01.getField("age");//参数就是变量名字
        System.out.println(age);
    }
}

运行结果:
在这里插入图片描述

getDeclaredFields()

package com.itxs.demo01;

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

/**
 * @Classname : demo05
 * @Description : TODO 反射获取类中的成员属性,进行赋值访问
 * @Author : lin_refuel@qq.com
 */
public class demo05 {
    public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
           // 反射获取一个对象
        Class<Student> stu01 = Student.class;
          // 获取stu01中所有的成员变量,
        Field[] s01 = stu01.getDeclaredFields();//成员变量数组
        // 进行遍历
        for (Field s : s01) {
            System.out.println(s);
        }
    }
}

运行结果:
在这里插入图片描述

getDeclaredField()

注意Student(学生类)中setAge方法

package com.itxs.demo01;

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

/**
 * @Classname : demo05
 * @Description : TODO 反射获取类中的成员属性,进行赋值访问
 * @Author : lin_refuel@qq.com
 */
public class demo05 {
    public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
           // 反射获取一个对象
        Class<Student> stu01 = Student.class;
         // 获取类中私有成员变量sex的方式 TODO getDeclareField(”变量名字“)
        Field sex = stu01.getDeclaredField("sex");
        System.out.println(sex);
        // 设置和访问里面变量名字的两种方式
        //方式一: 常规的访问方式
        // 获取里面的构造方法,获取 TODO 默认无参构造方法
        Student student = stu01.getDeclaredConstructor().newInstance();
        // sex设置
        student.setSex(1);
        System.out.println(student.getSex());//输出sex的值
        // ******************************************************
        //方式二:反射的方式
        sex.setAccessible(true);// sex是私有变量,先进行异常检测关闭
        sex.set(student,3);// 设置student对像里面的私有变量sex,TODO 可以绕开 student里面setAge里面的限制
        System.out.println(sex.get(student));//获取student里面的sex的值
    }
}

运行结果:
在这里插入图片描述

反射–获取类中的成员方法

package com.itxs.demo01;

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

/**
 * @Classname : demo06
 * @Description : TODO 反射 - 获取类中成员方法进行调用
 * @Author : lin_refuel@qq.com
 */
public class demo06 {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
         // 反射获取一个类
        Class<Student> stu01 = Student.class;
         // TODO 获取类里面所有公有的方法,包括继承父类中的公有方法
//        Method[] methods = stu01.getMethods();// Student类和父类中的公有成员方法数组
//        for (Method method : methods) {
//            System.out.println(method);
//        }
        //**********************************************************************
        // TODO 反射的方式获取类里面的所有方法,不包含父类中的公有方法
//        Method[] declaredMethods = stu01.getDeclaredMethods();
//        for (Method declaredMethod : declaredMethods) {
//            System.out.println(declaredMethod);
//        }
        //***********************************************************************
        // TODO 反射方式 获取类里面指定的成员方法
        // 获取类中公有成员方法 getMethod
        Method monPu = stu01.getMethod("monPu");//获取Student里面的monPu方法
        System.out.println(monPu);
        //第一种常规调用方式,调用公有方法monPu
        Constructor<Student> stu001 = stu01.getDeclaredConstructor(String.class, int.class, float.class);//获取一个私有构造方法
        stu001.setAccessible(true);//私有构造方法进行调用关闭异常检测
        Student s02 = stu001.newInstance("小肆", 18, 99);//构造方法实例化成对象
        s02.monPu("在下小肆");
        // 第二种调用方式调用里面的私有成员方法monPri
        // 获取私有成员方法使用 - getDeclaredMethod
        Method monPri = stu01.getDeclaredMethod("monPri", String.class);//获取到带一个参数的私有成员方法
        monPri.setAccessible(true);
        monPri.invoke(s02,"我是小肆二号");//调用实例化对象s02里面的monPri
    }
}

通过配置文件实现不同的程序功能

一个后缀名为txt的文件,通过修改Classname和fangfaming实现调用不同的类里面的方法

在这里插入图片描述

在demo02包里面定义一个学生类

package com.itxs.demo02;

/**
 * @Classname : Student
 * @Description : TODO 学生类
 * @Author : lin_refuel@qq.com
 */
public class Student {
    public void learn(){
        System.out.println("学生的职责就是好好学习,大概是可以早恋");
    }
}

在demo02里面定义一个教师类

package com.itxs.demo02;

/**
 * @Classname : Teacher
 * @Description : TODO 教师类
 * @Author : lin_refuel@qq.com
 */
public class Teacher {
   public void tuition(){
       System.out.println("老师的职责是好好教学,应该会注意学生早恋");
   }
}

demo03里面定义一个测试类

package com.itxs.demo03;

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;

/**
 * @Classname : demo01
 * @Description : TODO
 * @Author : lin_refuel@qq.com
 */
public class demo01 {
    public static void main(String[] args) throws IOException, NoSuchMethodException, ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException {
            // 通过配置文件的方式调用两个类中的方法
        FileReader fr = new FileReader("D:/JAVA/ce/My.txt");//读取的目标文件
           // 定义一个Properties,
        Properties prop = new Properties();
          // 读取目标文件fr里面的内容
        prop.load(fr);
        //测试读取
        //System.out.println(prop);
        //获取根据键获取对应的值
        String p1 = prop.getProperty("Classname");//类名字
        String p2 = prop.getProperty("fangfaming");//方法名字
        //通过反射获取对象
        Class<?> aClass = Class.forName("com.itxs.demo02." + p1);//获取到对象
        //获取对象的构造方法
        Constructor<?> c1 = aClass.getConstructor();
        //构造方法进行实例化
        Object o = c1.newInstance();
        //反射获取类中方法
        Method method = aClass.getMethod(p2);//
        //进行调用
        method.invoke(o);
        //关闭流
        fr.close();
    }
}

运行结果:

教师类测试
在这里插入图片描述
在这里插入图片描述
学生类测试
在这里插入图片描述
在这里插入图片描述

文章来源:https://blog.csdn.net/2301_81153022/article/details/135320031
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。