java反射详解

1 什么是java反射

1.1 什么是反射

  • 反射是程序在运行的过程中检测、修改、访问自身状态和行为的能力

1.2 什么是java反射

  • java的反射指的是程序在运行时,任意的一个类都能获取到属性和方法,任意一个对象都能调用方法和属性,这种动态的获取信息和动态调用方法的功能称之为java的反射机制
  • 一个类只能获取一个字节码对象
    如图
    在这里插入图片描述

1.3反射的作用

  • 在运行时判断任意一个对象所属的类;
  • 在运行构造任意一个类的对象;
  • 在运行时判断任何一个类所具有的方法和属性;
  • 在运行时调用任何一个对象的方法;

2 java反射的分类

  • 要想结果解剖一个类,必须先获取该类的字节码文件(.class)的对象,使用class类的方法进行解剖;
  • class类
  • field类
  • method类
  • construor类
  • annoation类

2.1 class类

2.1.1 获取class类的对象的三种方法

  • 对象点上getclass (public final native Class<?> getClass()
  • 类名点上class()
  • Class.forName(“完整的类名加上包名”)(public static Class forName(String className) throws ClassNotFoundException
    实例
package reflect;

public class Reflect {
    public static void main(String[] args) throws ClassNotFoundException {
        //获取类Student的字节码文件的3种方式
        //类名点上class
        Class<Student> studentClass = Student.class;
        System.out.println(studentClass);
        //通过对象获取
        Student student=new Student();
        Class aClass =  student.getClass();
        System.out.println(aClass);
        //通过完整的包名加上类名
        Class aClass1 = Class.forName("reflect.Student");
        System.out.println(aClass1);

    }
}

Student类

package reflect;

public class Student extends StudentSleepPlace implements Goal{
    public  String name;
    public char sex;
    public int age;
    private  Integer StudentID;
    Student(){};

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


    public int getStudentID() {
        return StudentID;
    }

    //设置学号
    public void setStudentID(Integer studentID) {
        StudentID = studentID;
    }

    public void study(){
        System.out.println("我在高一六班学习");
}

    @Override
    public void getGoal() {
        System.out.println("目标考大学");

    }
}

StudentSleepPlace类

package reflect;

public class StudentSleepPlace {
    public void placeOne(){
        System.out.println("宿舍睡觉");
    }
    public void placeTwo(){
        System.out.println("回家睡觉");
    }
    public void placeThree(){
        System.out.println("租房子睡觉");
    }
}

goal接口

package reflect;

public interface Goal {
        void getGoal();

}

2.1.2 class类的常用方法

方法描述
public String getName()获取完整的包名(包名+类名)
public String getSimpleName()获取类名
public Field[] getFields()获取被public修饰的Field的列表
public Field[] getDeclareFields()获取被public修饰的Field的列表
public Field[] getDeclareField(String name)根据属性名获取Field
public Method[] getDeclareMethods()获取类中的所有方法,但是不包括父类的方法
public Method getDeclareMethod(String name ,类<?>… parameterTypes,)根据方法名和方法形参获取一个指定方法
public Constructor[] getDeclareConstructors()获取类中的所有的构造方法
public Constructor etDeclareConstructor(String name ,类<?>… parameterTypes,)根据构造方法名和构造方法形参获取一个指定方法
public class<? super T> getSuperClass()获取父类的class对象
public class<? >[] getInterface()获取实现接口的集合
public native int getmodifiers获取该类的的修饰符
public T newInstance()获取该类的对象

2.1.3 示例

package reflect;

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

public class Reflect {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InstantiationException {

        //类名点上class,获取,class文件字节码的对象
        Class<Student> studentClass = Student.class;
        //获取类的全量名
        String name = studentClass.getName();
        System.out.println(name);
        System.out.println("==========================");
        //获取类的类名
        String simpleName = studentClass.getSimpleName();
        System.out.println(simpleName);
        System.out.println("==========================");
        //获取被public修饰的属性列表
        Field[] fields = studentClass.getFields();
        for (int i = 0; i <fields.length ; i++) {
            System.out.println(fields[i]);
        }
        System.out.println("==========================");
        //获取类中所有的属性
        Field[] declaredFields = studentClass.getDeclaredFields();
        for (int i = 0; i <declaredFields.length ; i++) {
            System.out.println(declaredFields[i]);
        }
        System.out.println("==========================");
        //获取指定属性
        Field name1 = studentClass.getDeclaredField("name");
        System.out.println(name1);
        System.out.println("==========================");
        //获取所有的方法
        Method[] declaredMethods = studentClass.getDeclaredMethods();
        for (int i = 0; i <declaredMethods.length ; i++) {
            System.out.println(declaredMethods[i]);
        }
        System.out.println("==========================");
        //根据方法名指定方法
        Method setStudentID = studentClass.getDeclaredMethod("setStudentID", Integer.class);
        System.out.println(setStudentID);
        System.out.println("==========================");
        //打印所有的构造方法
        Constructor<?>[] declaredConstructors = studentClass.getDeclaredConstructors();
        for (int i = 0; i <declaredConstructors.length; i++) {
            System.out.println(declaredConstructors[i]);

        }
        System.out.println("==========================");
        //根据class的类型和形式参数类型获取指定的方法
        Constructor<Student> declaredConstructor = studentClass.getDeclaredConstructor(String.class, int.class, char.class);
        System.out.println(declaredConstructor);
        System.out.println("==========================");
        //获取父类的字节码文件的对象
        Class<? super Student> superclass = studentClass.getSuperclass();
        System.out.println(superclass);
        System.out.println("==========================");
        //获取该类实现接口的列表
        Class<?>[] interfaces = studentClass.getInterfaces();
        System.out.println(interfaces.toString());
        System.out.println("==========================");
        //获取类的修饰符的类型
        int modifiers = studentClass.getModifiers();
        System.out.println(modifiers);//1代表public
        System.out.println("==========================");
        //获取Student的一个对象
        Student student = studentClass.newInstance();
        int age = student.age;
        System.out.println(age);

    }
}

在这里插入图片描述

2.2 Field类

2.2.1 Field类的常用方法

方法描述
public String getName()获取属性的方法名
public int getmodifiers()获取属性修饰符,返回的是一个数字,一般配置modify类的toString(int a)方法使用
public class<?> getType()获取属性的类型
public void set(Object obj,value)为属性赋值
public object get(Object obj)获取属性的值
public void setAccessible(boolean flag)true打破封装

2.2.2 示例

package reflect;


import java.lang.reflect.Field;
import java.lang.reflect.Modifier;


public class Reflect {
    public static void main(String[] args) throws Exception {
        //获取Student类的属性,并为属性赋值

        // 获取class对象
        Class<Student> studentClass = Student.class;
        //获取该类的所有参数
        Field[] Allfields = studentClass.getDeclaredFields();
        //获取参数的名称
        for(Field field:Allfields){
            //获取属性的修饰符和名称
            System.out.println(Modifier.toString(field.getModifiers())+"  "+field.getName());
        }
        //获取一个指定的参数
        Field name = studentClass.getDeclaredField("name");
        //获取一个Student的对象
        Student student = studentClass.newInstance();
        //为name赋值
        name.set(student,"小王");
        //获取这个值
        Object o = name.get(student);
        System.out.println(o);

        Field studentID = studentClass.getDeclaredField("StudentID");
        //为私有的参数赋值必须先调用setAccessible方法并设置为true
        studentID.setAccessible(true);
        studentID.set(student,12);
        Object o1 = studentID.get(student);
        System.out.println(o1);
    }
}

2.3 Method 方法

2.3.1 Method常用方法

方法描述
public String getName()获取属性的方法名
public int getmodifiers()获取方法修饰符,返回的是一个数字,一般配置modify类的toString(int a)方法使用
public class<?> getReturnType()获取方法的返回类型
public class<?> getParameterType()获取方法的形式参数类型
public void invoke(Object obj,patameters…type)调用方法

2.3.2 示例

package reflect;


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

public class Reflect {
    public static void main(String[] args) throws Exception {

        //获取class的对象
        Class<?> Student = Class.forName("reflect.Student");

        //获取方法的对象
        Method[] allMethods = Student.getDeclaredMethods();


        for (int i = 0; i <allMethods.length ; i++) {
            //生成一个ArrayList存储形式参数的类型
            ArrayList arrayList=new ArrayList();

            Class<?>[] parameterTypes = allMethods[i].getParameterTypes();
            for (int j = 0; j < parameterTypes.length; j++) {
                arrayList.add(parameterTypes[j].getSimpleName());
            }
            //打印方法
            System.out.println(Modifier.toString(allMethods[i].getModifiers())+"  "+allMethods[i].getReturnType()+"  "+allMethods[i].getName()+"(" +arrayList.toString()+")");
        }
        System.out.println("===========================");
        //调用方法
        //获取一个指定的方法对象
        Method setStudentID = Student.getDeclaredMethod("setStudentID", Integer.class);
        //获取class的对象
        Student o = (Student) Student.newInstance();
        //调用方法
        setStudentID.invoke(o,12);
        System.out.println(o.getStudentID());

    }
}

在这里插入图片描述

2.4 Constructor类

2.4.1 Constructor常用方法

方法描述
public String getName()获取属性的方法名
public int getmodifiers()获取构造方法修饰符,返回的是一个数字,一般配置modify类的toString(int a)方法使用
public class<?> getParameterType()获取方法的形式参数类型
public T invoke(patameters…type)创建一个对象

2.4.2 示例

package reflect;


import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.ArrayList;

public class Reflect {
    public static void main(String[] args) throws Exception {

        //获取class的对象
        Class<?> Student = Class.forName("reflect.Student");

        //获取构造方法的对象
        Constructor<?>[] allConstructors = Student.getDeclaredConstructors();
        for (Constructor constructor:allConstructors){
            //存储构造方法的形式参数
            ArrayList arrayList=new ArrayList();
            //获取构造方法的形式参数的类型
            Class[] parameterTypes = constructor.getParameterTypes();
            //存储形式参数
            for (Class<?> classType:parameterTypes){
                arrayList.add(classType.getSimpleName());
            }
            System.out.println(Modifier.toString(constructor.getModifiers())+"  "+constructor.getName()+"("+arrayList.toString()+")");
        }
        //获取指定的构造方法
        Constructor<?> declaredConstructor = Student.getDeclaredConstructor(String.class, int.class, char.class);
        //指定的类
        Student students = (Student)declaredConstructor.newInstance("张三", 12, '男');
        System.out.println(students.sex);
        System.out.println(students.name);
        System.out.println(students.age);
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java反射机制是指在运行时动态地获取一个类的信息,并可以操作类的属性、方法和构造器等。Java反射机制可以使程序员在运行时动态地调用类的方法和属性,扩展类的功能,并可以实现注解、工厂模式以及框架开发等。 Java反射机制的原理如下:首先,Java编译器将Java源代码编译为字节码文件,字节码文件中包含着类的信息,这些信息包括类的名称、方法、属性和构造器等等。接着,Java虚拟机将字节码文件加载到内存中,然后通过类加载器将类加载到内存中形成一个类对象,这个类对象可以操作字节码文件中的信息。 使用Java反射机制的过程如下:首先获取类对象,通过类对象来获取类的构造器、属性、方法等信息,然后调用构造器来创建对象,通过属性获取和设置类的成员属性,通过方法调用类的方法等。 Java反射机制的优点是可以在运行时动态地得到类的信息,使得程序员在程序运行时能够对类进行更加灵活的操作,并可以使得程序更加通用化,同时也存在着一定的性能问题,因为Java反射机制需要Java虚拟机进行一定的额外处理,所以在程序运行时需要进行额外的时间和资源消耗。 总之,Java反射机制是Java语言的一项重要特性,在Java开发中广泛应用,在代码编写、框架开发以及API开发中具有重要作用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值