java根据field名获取变量_javaSE第十二部分 Java的反射机制

反射(reflection),Java的反射是指程序在运行期可以拿到一个对象的所有信息。

在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法。

与Java反射相关的类如下:

	Class类:代表类的实体,在运行的Java应用程序中表示类和接口
	Field类:代表类的成员变量(成员变量也称为类的属性)
	Method类:代表类的方法
	Constructor类:代表类的构造方法

Class类:获取Class类的对象,该对象就是我们定义的某个class,比如Person类、Student类

我们借用廖雪峰老师的话来说一下class

Class类​www.liaoxuefeng.com
1385d65277e9596d6f8a14d214cb240e.png

除了int等基本类型外,Java的其他类型全部都是class。仔细思考,我们可以得出结论:class(包括interface)的本质是数据类型(Type)。

而class是由JVM在执行过程中动态加载的。JVM在第一次读取到一种class类型时,将其加载进内存。

每加载一种class,JVM就为其创建一个Class类型的实例,并关联起来。注意:这里的Class类型是一个名叫Class的class。它长这样:

	public final class Class {
		private Class() {}
	}

以String类为例,当JVM加载String类时,它首先读取String.class文件到内存,然后,为String类创建一个Class实例并关联起来:

Class cls = new Class(String);

这个Class实例是JVM内部创建的,如果我们查看JDK源码,可以发现Class类的构造方法是private,只有JVM能创建Class实例,我们自己的Java程序是无法创建Class实例的。

以上就是廖雪峰老师对Class的解释。

获取Class的对象的方式:

	1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
		多用于配置文件,将类名定义在配置文件中。读取文件,加载类
                这个是不是很熟悉,我们在加载mysql驱动的时候就是这样加载的
	2. 类名.class:通过类名的属性class获取
		多用于参数的传递
	3. 对象.getClass():getClass()方法在Object类中定义着。
		多用于对象的获取字节码的方式

* 结论:

同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个,地址相同。

通过Class的对象来获取成员变量、构造方法、成员方法和全类名

1. 获取成员变量们

	Field[] getFields() :获取所有public修饰的成员变量
	Field getField(String name)   获取指定名称的 public修饰的成员变量
	Field[] getDeclaredFields()  获取所有的成员变量,不考虑修饰符
	Field getDeclaredField(String name)  

2. 获取构造方法们

	Constructor<?>[] getConstructors()  
	Constructor<T> getConstructor(类<?>... parameterTypes)  
	Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)  
	Constructor<?>[] getDeclaredConstructors()  

3. 获取成员方法们:

	Method[] getMethods()  
	Method getMethod(String name, 类<?>... parameterTypes)  
	Method[] getDeclaredMethods()  
	Method getDeclaredMethod(String name, 类<?>... parameterTypes)  

4. 获取全类名

	String getName()  

Field类:成员变量

1. 设置值

	void set(Object obj, Object value)  

2. 获取值

	get(Object obj) 

3. 忽略访问权限修饰符的安全检查

	setAccessible(true):暴力反射

Constructor类:构造方法

创建对象

	T newInstance(Object... initargs)  

* 如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法

Method类:方法对象

* 执行方法:

	Object invoke(Object obj, Object... args)  

* 获取方法名称:

	String getName():获取方法名

写了一个测试类:

package demo.reflection;

import org.junit.Assert;
import org.junit.Test;

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

public class ReflectDemo {

    @Test
    public void testClass() throws ClassNotFoundException {
        Class cls1 = Class.forName("demo.reflection.Student");
        Class cls2 = Student.class;
        Student s = new Student();
        Class cls3 = s.getClass();
        System.out.println(cls1);
        System.out.println(cls1.getName());
        Assert.assertEquals(true,cls1 == cls2);
        Assert.assertEquals(true,cls1 == cls3);
    }

    @Test
    public void testField() throws NoSuchFieldException, IllegalAccessException {
        Class cls = Student.class;
        Field[] fields = cls.getFields();
        Field[] declaredFields = cls.getDeclaredFields();
        for (Field field : fields) {
            System.out.println(field);
        }
        System.out.println("---------------------------------");
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
        System.out.println("---------------------------------");
        Field name = cls.getField("name");
        System.out.println(name);
        Student student = new Student();
        Object nameValue = name.get(student);
        System.out.println(nameValue);
        name.set(student,"zhangsan");
        Object nameValue2 = name.get(student);
        System.out.println(nameValue2);
        System.out.println("---------------------------------");
        Field age = cls.getDeclaredField("age");
        System.out.println(age);
    }

    @Test
    public void testConstructor() throws Exception {
        Class cls = Student.class;
        Constructor[] cons = cls.getConstructors();
        Constructor noParaCon = cls.getConstructor();
        Constructor havaParaCon = cls.getConstructor(String.class,String.class,int.class,String.class);
        for (Constructor con : cons) {
            System.out.println(con);
        }
        System.out.println("------------------------------");
        System.out.println(noParaCon);
        System.out.println("------------------------------");
        System.out.println(havaParaCon);
        System.out.println("------------------------------");
        Object student = havaParaCon.newInstance("tom","s0001",25,"男");
        System.out.println(student);
    }

    @Test
    public void testMethod() throws Exception {
        Class cls = Student.class;
        Method[] methods = cls.getMethods();
        Method[] declaredMethods = cls.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        //Assert.assertEquals(9,methods.length);  //其实把继承自Object的方法也列出来了
        System.out.println("---------------------------");
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
        Assert.assertEquals(10,declaredMethods.length);
        System.out.println("---------------------------");
        Method eat = cls.getDeclaredMethod("eat",String.class);
        System.out.println(eat);
        System.out.println(eat.getName());
        Student student = new Student();
        eat.setAccessible(true);
        eat.invoke(student,"薯片");
    }
}

输出如下:

d6c83980140f346c2774cdaecb94eff3.png
class demo.reflection.Student
demo.reflection.Student



public java.lang.String demo.reflection.Student.name
public java.lang.String demo.reflection.Student.stuId
---------------------------------
public java.lang.String demo.reflection.Student.name
public java.lang.String demo.reflection.Student.stuId
private int demo.reflection.Student.age
private java.lang.String demo.reflection.Student.sex
---------------------------------
public java.lang.String demo.reflection.Student.name
null
zhangsan
---------------------------------
private int demo.reflection.Student.age



public java.lang.String demo.reflection.Student.toString()
public java.lang.String demo.reflection.Student.getName()
public void demo.reflection.Student.setName(java.lang.String)
public java.lang.String demo.reflection.Student.getStuId()
public int demo.reflection.Student.getAge()
public java.lang.String demo.reflection.Student.getSex()
public void demo.reflection.Student.setStuId(java.lang.String)
public void demo.reflection.Student.setAge(int)
public void demo.reflection.Student.setSex(java.lang.String)
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final void java.lang.Object.wait() 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 demo.reflection.Student.toString()
public java.lang.String demo.reflection.Student.getName()
public void demo.reflection.Student.setName(java.lang.String)
private void demo.reflection.Student.eat(java.lang.String)
public java.lang.String demo.reflection.Student.getStuId()
public int demo.reflection.Student.getAge()
public java.lang.String demo.reflection.Student.getSex()
public void demo.reflection.Student.setStuId(java.lang.String)
public void demo.reflection.Student.setAge(int)
public void demo.reflection.Student.setSex(java.lang.String)
---------------------------
private void demo.reflection.Student.eat(java.lang.String)
eat
eat薯片 ... 



public demo.reflection.Student()
public demo.reflection.Student(java.lang.String,java.lang.String,int,java.lang.String)
------------------------------
public demo.reflection.Student()
------------------------------
public demo.reflection.Student(java.lang.String,java.lang.String,int,java.lang.String)
------------------------------
Student{name='tom', stuId='s0001', age=25, sex='男'}

其中Student类为:

package demo.reflection;

public class Student {
    public String name;
    public String stuId;
    private int age;
    private String sex;

    public Student() {
    }

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

    private void eat(String thing){
        System.out.println("eat" + thing +" ... ");
    }

    public String getName() {
        return name;
    }

    public String getStuId() {
        return stuId;
    }

    public int getAge() {
        return age;
    }

    public String getSex() {
        return sex;
    }

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

    public void setStuId(String stuId) {
        this.stuId = stuId;
    }

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

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + ''' +
                ", stuId='" + stuId + ''' +
                ", age=" + age +
                ", sex='" + sex + ''' +
                '}';
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值