JAVA-基础 反射

反射

反射:加载类,并允许以编程的方式解剖类中的各种成分,成员变量,方法,构造器等等;

反射的作用,反射主要还是用来做框架

 

反射学什么?学习获取类的信息并操作他们

1,反射第一步,加载类,获取类的字节码,class对象

2,获取类的构造器,construceor对象

3,获取类的成员变量,field对象

4,获取对象的成员方法, method对象

 

获取类的Class对象的三种方式

1,Class c1 = 类名.class

 

2,调用Class提供的方法: public static Class forName(String package); 获取class对象

 

3,Object提供的方法: public Class getClass(); Class c3 = 对象.getClass();

 

 

获取类中的构造器

例如我们想要获取上述中Student的类构造器

package org.example;

import java.lang.reflect.Constructor;

public class TestClass2 {
    public static void main(String[] args) {
        Class c1 = Student.class;
        for (Constructor constructor : c1.getConstructors()) {
            System.out.println(constructor); //constructor构造器
            System.out.println(constructor.getName()+"构造器参数数量: "+constructor.getParameterCount()); //getParameterCount获取构造器参数数量
        }
    }
}

打印之后则会输出

public org.example.Student(java.lang.String,int)
org.example.Student构造器参数数量: 2
public org.example.Student()
org.example.Student构造器参数数量: 0

 

其他的方法(代码实例):

package org.example;

import java.lang.reflect.Constructor;

public class TestClass2 {
    public static void main(String[] args) throws NoSuchMethodException {
        Class c1 = Student.class;
        for (Constructor constructor : c1.getConstructors()) {
            System.out.println(constructor); //constructor构造器
            System.out.println(constructor.getName()+"构造器参数数量: "+constructor.getParameterCount()); //getParameterCount获取构造器参数数量
        }
        for (Constructor declaredConstructor : c1.getDeclaredConstructors()) {
            System.out.println(declaredConstructor.getName());

            /**
             * getDeclaredConstructors获取全部构造器包括私有成员
             * 可以无视修饰符修饰后的构造器
             */
        }

        //getConstructor获取单个构造器,只能拿public修饰的构造器
        Constructor constructor = c1.getConstructor(); //无参构造器
        Constructor constructor2 = c1.getConstructor(String.class,int.class); //有参构造器

        //getDeclaredConstructor可以获取任何类型的构造器
        Constructor dconstructor = c1.getDeclaredConstructor(); //无参构造器
        Constructor dconstructor2 = c1.getDeclaredConstructor(String.class,int.class); //有参构造器
    }
}

 

 

通过反射获取类的构造器的作用: 依旧是初始化类的对象并且返回

Construcror提供的方法

//getConstructor获取单个构造器,只能拿public修饰的构造器
Constructor<Student> constructor = c1.getConstructor(); //无参构造器
Constructor constructor2 = c1.getConstructor(String.class,int.class); //有参构造器

//getDeclaredConstructor可以获取任何类型的构造器
Constructor<Student> dconstructor = c1.getDeclaredConstructor(); //无参构造器
Constructor dconstructor2 = c1.getDeclaredConstructor(String.class,int.class); //有参构造器

dconstructor.setAccessible(true); //设置true可以暴力反射对象,无视私有属性
Student s = dconstructor.newInstance(); //newInstance初始化对象并且返回
System.out.println(s);

 

 

通过反射获取类的成员变量,并且对成员变量进行操作

@Test
public void testOprFieldClass() throws NoSuchMethodException, NoSuchFieldException, IllegalAccessException {
    //第一步, 获取类的Class对象
    Class c1 = Student.class;

    /**
     * 第二步,获取类全部的成员变量
     * getFields 只获取public修饰的成员变量
     * getDeclaredFields获取所有成员变量
     * getField 获取单个成员变量 只获取public修饰的成员变量
     * getDeclaredField 获取单个成员变量,不过可以获取任意成员变量
     */
    Field[] fields = c1.getDeclaredFields();
    for (Field field : fields) {
        System.out.println("成员变量: "+field.getName()+"---->"+field.getType());
        //getName获取成员变量名字,getType获取成员变量类型
    }
    Field field =  c1.getDeclaredField("name");
    field.setAccessible(true); //暴力反射
    Student s = new Student(); //实例化Student对象
    field.set(s,"小明"); //set给成员变量进行赋值
    System.out.println(s.toString());
    System.out.println(field.get(s)); //get取值

}

 

 

通过反射获取类的成员方法,并且对成员方法进行操作

@Test
public void testOprMethodClass() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    //第一步,获取反射Class对象
    Class c1 = Student.class;

    /**
     * 2,获取类的全部成员方法
     */
    Method[] methods = c1.getDeclaredMethods();
    for (Method method : methods) {
        System.out.println(method.getName()); //getname获取成员方法名称
        System.out.println(method.getParameterCount()); //getParameterCount获取方法参数数量
        System.out.println(method.getReturnType()); //获取成员方法返回类型
    }
    Student student = new Student("小明",12);
    Method run = c1.getMethod("getName");
    run.setAccessible(true);
    Object rs = run.invoke(student);
    System.out.println(rs);
}

 

反射的作用

基本作用:

1,获取一个类的全部成分然后进行操作

2,并且可以破坏封装性

3,适合做JAVA的框架,主流的框架都会基于反射设计出来一些通用的功能

 

 

 

 

发表回复

电子邮件地址不会被公开。必填项已用 * 标注