Java反射机制及简单实现

1、什么是Java的反射机制
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。(定义来自网络书籍)

2、Java反射中用到的几个对象
在反射实现中主要用到的几个对象Class、Constructor、Field、Method
2.1 Class:对于任何一个你想操作的类对象,首先都须要将它转化成一个CLass对象然后通过一些JDK的API才能进行进一步的操作。
获得Class对象有三种方法:
  		// 1、通过类来获得Class对象
Class<?> clazz1 = Person.class;

// 2、通过Class.forName(含包路径的类类)获得Class对象;
Class<?> clazz2 = Class.forName("com.leiht.reflect.Person");

// 3、通过类类的一个实例.getClass()获得Class对象
Class<?> clazz3 = new Person().getClass();

2.2 Constructor:帮名思义,此对象是用来获取及操作目标对象的构造方法(包括有参和无参的)
获取Constructor对象:
// 使用无参/默认构造器创建对象实例
Class<?> clazz = Person.class;
Person person = (Person) clazz.newInstance();
System.out.println(person);

//通过Constructor对象实现对构造方法的反射
//如果构造方法为private(单例模式)则用getDeclaredConstructor(...)方法
Constructor<Person> con = (Constructor<Person>) clazz.getConstructor(int.class, String.class, int.class);


2.3 Field:用于对目标对象的属性操作
获取Field对象:
   //通过字段名获取公有字段
Field f1 = clazz.getField("id");


2.4 Method对象:此对象是用于获取目标类的方法及其相关的操作
获取Field对象
 //通过类类的一个实例.getClass()获得Class对象
Class<?> clazz = person.getClass();

Method m = clazz.getMethod("getAge");
int age = (int) m.invoke(person);
·



3、关于反射的简单实现代码(可参考)
3.1 目标对象
package com.leiht.reflect;

public class Person {

private static String TAG = "Tag";
public int id;
private String name;
private int age;

public Person() {
}

public Person(int id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
}

public int sum(int...numbers) {
if (numbers.length==0) return -1;
int total = 0;
for (int n : numbers)
total += n;
return total;
}

public static String getTAG() {
return TAG;
}

public static void setTAG(String tAG) {
TAG = tAG;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

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;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return this.id + this.name + this.age;
}
}


3.2 获取Class对象
package com.leiht.reflect;

import com.leiht.reflect.util.ToStringUtil;

/**
* 取得Class对象的三种方法
*
* @author Leiht
*
*/
public class ReflectClass {

public static void main(String[] args) throws Exception {
// 1、通过类来获得Class对象
Class<?> clazz1 = Person.class;

// 2、通过Class.forName(含包路径的类类)获得Class对象;
Class<?> clazz2 = Class.forName("com.leiht.reflect.Person");

// 3、通过类类的一个实例.getClass()获得Class对象
Class<?> clazz3 = new Person().getClass();

// 三种方式获得的Class对象均是相同的,返回true
System.out.println(clazz1 == clazz2);
System.out.println(clazz2 == clazz3);

System.out.println(ToStringUtil.toString(new Person(1000, "雷洪太", 26)));

}
}


3.3 对构造方法Constructor的操作
package com.leiht.reflect;

import java.lang.reflect.Constructor;

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

// 使用无参/默认构造器创建对象实例
Class<?> clazz = Person.class;
Person person = (Person) clazz.newInstance();
System.out.println(person);

//通过Constructor对象实现对构造方法的反射
//如果构造方法为private(单例模式)则用getDeclaredConstructor(...)方法
Constructor<Person> con = (Constructor<Person>) clazz.getConstructor(int.class, String.class, int.class);
Person p = con.newInstance(100,"lisi",29);
System.out.println(p);
}
}

3.4 对Field的操作
package com.leiht.reflect;

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

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

Person person = new Person(100, "zhangsan", 18);

//通过类类的一个实例.getClass()获得Class对象
Class<?> clazz = person.getClass();

//通过字段名获取公有字段
Field f1 = clazz.getField("id");
//Field对象
System.out.println(f1);
//通过Field和person实例取值
Object obj1 = f1.get(person);
System.out.println(obj1);

//取得私有字段
Field f2 = clazz.getDeclaredField("name");
System.out.println(f2);
f2.setAccessible(true);
Object obj2 = f2.get(person);
System.out.println(obj2);
Field f3 = clazz.getDeclaredField("age");
System.out.println(f3);
f3.setAccessible(true);
f3.set(person, 20);
Object obj3 = f3.get(person);
System.out.println(obj3);
System.out.println(person.getAge());

//获取静态字段
Field f4 = clazz.getDeclaredField("TAG");
System.out.println(f4);
//判断是否为静态字段
System.out.println("该字段是否是静态字段" + Modifier.isStatic(f4.getModifiers()));
f4.setAccessible(true);
System.out.println(f4.get(null));
System.out.print("设置 : ");
f4.set(null, "new value");
System.out.println(Person.getTAG());

}
}


3.5 对Method的简单操作
package com.leiht.reflect;

import java.lang.reflect.Method;

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

Person person = new Person(100, "zhangsan", 18);

//通过类类的一个实例.getClass()获得Class对象
Class<?> clazz = person.getClass();

Method m = clazz.getMethod("getAge");
int age = (int) m.invoke(person);
System.out.println(age);

Method setMethod = clazz.getMethod("setAge", int.class);
setMethod.invoke(person, 28);
System.out.println(person.getAge());

Method arrayMethod = clazz.getDeclaredMethod("sum", int[].class);
int result = (Integer) arrayMethod.invoke(person, new int[]{1,2,3});
System.out.println(result);
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值