栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java中的反射

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java中的反射

反射 1、反射概述

类的信息:成员变量,构造方法,成员方法 等。

2、获取Class类的对象 2.1、理论

Class 类:

Class是一个类 , 位于java.lang包下。

在Java中每个类都有一个相对应的Class类的对象。

Java程序在启动运行时,一个 XXX.java 文件经过编译生成 XXX.class 文件后,就会在JVM虚拟机中产生一个XXX类对应的Class类的对象,用于表示这个XXX类的类型信息。

2.2、代码

上面代码 的运行结果为:

class com.itheima_02.Student
true
--------
true
--------
true
3、反射获取构造方法并使用 3.1、理论

Class 类中,用于 获取构造方法 的方法 :

getConstructors():获取类中的 所有公共构造方法getConstructor(Class[] params): 获取类的特定构造方法 。 params:指定构造方法的参数类型getDeclaredConstructors(): 获取类中的 所有构造方法 (public、protected、default、private)getDeclaredConstructor(Class[] params): 获取类中的 特定构造方法。params:指定构造方法的参数类型

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

T newInstance(Object…initargs) :根据指定的构造方法,创建对象

使用私有构造方法对象,创建对象:

public void setAccessible (boolean flag) :

Constructor 类中的方法。flag的值为true,则取消访问检查,这样的话,私有构造方法对象 也可以创建对象了。若 flag不设为true,私有构造方法对象 不可以创建对象。

反射获取构造方法并创建对象的 步骤:

得到class对象通过class对象,调用 get(Declared)Constructor 方法,得到 构造方法对象通过构造方法对象,调用 newInstance 方法,方法的参数为初始值,得到 要创建的对象 (如:student对象) 3.2、代码

Student 类:

【 reflect 包下,有两个类,分别是 Student ,ConstructorDemo 】

package reflect;

public class Student {
    
    private int age;
    String name;
    public String address;
	
    // 公共无参构造方法
    public Student(){}

    // 公共有参构造方法
    public Student(int age, String name, String address) {
        this.age = age;
        this.name = name;
        this.address = address;
    }

    // 默认构造方法
    Student(String name, String address){
        this.name = name;
        this.address = address;
    }


    // 私有构造方法
    private Student(int age, String name){
        this.age = age;
        this.name = name;
    }
    
    // 私有 方法 method1
    private String method1(String s){
        System.out.println("method1 被执行");
        return "method1"+s;
    }

    // 默认 方法 method2
    String method2(){
        return "method2";
    }

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + ''' +
                ", address='" + address + ''' +
                '}';
    }
}

获取 构造方法对象 的演示代码:

package reflect;

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


public class ConstructorDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class c1 = Class.forName("reflect.Student");

        Constructor[] constructors = c1.getConstructors();

        Constructor[] declaredConstructors = c1.getDeclaredConstructors();

        Constructor constructor = c1.getConstructor();

        Constructor declaredConstructor = c1.getDeclaredConstructor(String.class, String.class);

        System.out.println(constructor);
        System.out.println(declaredConstructor);
        System.out.println("--------");

        for (Constructor con:declaredConstructors) {
            System.out.println(con);
        }

        System.out.println("--------");
        
        Student s = new Student();
        System.out.println(s);
        
        Object obj = constructor.newInstance();
        System.out.println(obj);

        Object obj2 = declaredConstructor.newInstance("Mike","西安");
        System.out.println(obj2);
        
        System.out.println("--------");
        Constructor declaredConstructor2 = c1.getDeclaredConstructor(int.class, String.class);
        System.out.println(declaredConstructor2);

        declaredConstructor2.setAccessible(true); // 若没有此行代码,会出现 IllegalAccessException
        Object o = declaredConstructor2.newInstance(18, "Lucy");
        System.out.println(o);

    }
}

// 上面代码的执行结果为:
public reflect.Student()
reflect.Student(java.lang.String,java.lang.String)
--------
private reflect.Student(int,java.lang.String)
reflect.Student(java.lang.String,java.lang.String)
public reflect.Student(int,java.lang.String,java.lang.String)
public reflect.Student()
--------
Student{age=0, name='null', address='null'}
Student{age=0, name='null', address='null'}
Student{age=0, name='Mike', address='西安'}
--------
private reflect.Student(int,java.lang.String)
Student{age=18, name='Lucy', address='null'}
4、反射获取成员变量并使用 4.1、理论

获取类中的属性:

Field[] getFields(): 获取 public 类型的成员变量对象 的数组Field getField(String name): 获取单个的public 类型的 成员变量对象,name参数指定了成员变量的名称Field[] getDeclaredFields(): 获取所有的成员变量对象的数组 (public、protected、default、private),但不包括继承的属性。Field getDeclaredField(String name): 获取单个的成员变量对象(public、protected、default、private),name参数指定了成员变量的名称 Field 类中用于给成员变量赋值的方法:

void set(Object obj , Object value) : 给obj 对象的成员变量赋值为 value。Field 对象会调用此方法,此Field 对象 对应着 obj 的某个成员变量例如: addressField.set(obj,"北京") 这段代码的意思是:将指定的对象参数(obj)中,由此field对象(addressField) 表示的字段(obj对象的address字段)设置为新值(北京) public void setAccessible (boolean flag) :

Field 中的方法。flag的值设为true,则取消访问检查。若 flag的值不设为true,当字段的修饰符不为public时,会出现 IllegalAccessException(非法访问异常) 4.2、代码

【 reflect 包下,有两个类,分别是 Student (见3.2中),FieldDemo】

package reflect;

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

public class FieldDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class c = Class.forName("reflect.Student");

        Field[] fields = c.getFields();

        Field[] declaredFields = c.getDeclaredFields();

        for (Field field:declaredFields) {
            System.out.println(field);
        }
        System.out.println("--------");

        Field addressField = c.getField("address");
        System.out.println(addressField);

        Field nameField = c.getDeclaredField("name");

        // 获取无参构造方法,创建对象
        Constructor constructor = c.getConstructor();
        Object obj = constructor.newInstance();

        System.out.println("--------");

        // void set(Object obj,Object value)
        // 将指定的对象参数(obj)中,由此field对象(addressField) 表示的字段(obj对象的address字段)设置为新值(北京)
        addressField.set(obj,"北京");
        System.out.println(obj);

    }
}
// 上面代码的执行结果为:
private int reflect.Student.age
java.lang.String reflect.Student.name
public java.lang.String reflect.Student.address
--------
public java.lang.String reflect.Student.address
--------
Student{age=0, name='null', address='北京'}
5、反射获取成员方法并使用 5.1、理论

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

Method[] getMethods(): 返回所有的 公共成员方法对象 的数组。包括父类(如:Object)的 公共成员方法对象Method[] getDeclaredMethods(): 返回所有的 成员方法对象 的数组 (public、protected、default、private)。不包括父类(如:Object)的 成员方法对象Method getMethod(String name,Class…parameterTypes): 返回单个的公共成员方法对象。第一个参数name 指定了成员方法的名称,第二个参数 为 对应方法的 参数类型。包括父类(如:Object)的 公共成员方法对象Method getDeclaredMethod(String name,Class…parameterTypes): 返回单个的成员方法对象(public、protected、default、private)。第一个参数name 指定了成员方法的名称,第二个参数 为 对应方法的 参数类型。不包括父类(如:Object)的 成员方法对象

Method 类中,用于调用成员方法的方法

Object invoke(Object obj,Object…args):调用 obj对象 的 成员方法

Object :返回值类型Object obj:调用方法的对象Object…args:被调用方法 需要的参数 5.2、代码

【 reflect 包下,有两个类,分别是 Student ,MethodDemo】

package reflect;

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

public class MethodDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        
        Class c = Class.forName("reflect.Student");

        // 返回所有的 公共成员方法对象 的数组,包括父类(如:Object)的 公共成员方法对象
        Method[] methods = c.getMethods();

        // 返回所有的 成员方法对象 的数组,不包括父类(如:Object)的 成员方法对象
        Method[] declaredMethods = c.getDeclaredMethods();

        for(Method method:methods){
            System.out.println(method);
        }
        System.out.println("--------");


        for(Method method:declaredMethods){
            System.out.println(method);
        }
        System.out.println("--------");

        // 获取无参构造方法对象,并用它来 创建 obj(student) 对象
        Constructor constructor = c.getConstructor();
        Object obj = constructor.newInstance();

        // 通过class对象c ,调用 getDeclaredMethod方法,得到私有方法 method1 所对应的 method对象 method1Method
        Method method1Method = c.getDeclaredMethod("method1", String.class);
        method1Method.setAccessible(true);// 取消访问检查。因为 此处要访问私有方法 method1

        
       
        
        Object result = method1Method.invoke(obj, "哈哈哈");
        System.out.println(result);


    }
}
// 上面代码的执行结果为:
public java.lang.String reflect.Student.toString()
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
--------
public java.lang.String reflect.Student.toString()
private java.lang.String reflect.Student.method1(java.lang.String)
java.lang.String reflect.Student.method2()
--------
method1 被执行
method1哈哈哈
6、练习: 6.1、题目:

往 ArrayList 集合中,添加一个字符串数据。

6.2、代码
public class Test {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        
        ArrayList arrayList = new ArrayList<>();
        // 得到 arrayList 的class对象
        Class c = arrayList.getClass();
        
        // 得到method对象
        Method addMethod = c.getMethod("add", Object.class);

        addMethod.invoke(arrayList,12);
        addMethod.invoke(arrayList,"Hello"); // 往 arrayList 中,添加字符串数据

        System.out.println(arrayList); // [12, Hello]
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/755962.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号