基本概念:
把内存代码区的class(字节码文件)看作是一个类,该类包含所有当前字节码文件的内容,通过一些方式可以获取到里面的Consturctor(构造方法),Method(成员方法)和Filed(成员变量)
获取Class类对象的方式
- Class.forName("完整的包名.类名")
(最常用、各种驱动加载,jdbc、Mybaits) - 类.class
- 类对象。getClass()
构造函数的反射
Constructor构造方法类:
- Constructor[] getConstructors()
--获取类内非私有化的构造方法 - Constructor[] getDeclaredConstructors();
--暴力反射可以获取私有化构造函数 - Constructor getConstructor(Class...paramterTypes);
--.getConstructor(int.class); - Constructor[] getConstructors(Class... parameterTypes);
--不定长参数列表。不限制参数个数,但是类型必须是Class
-- 根据传入的类型,来确定要返回的构造函数是哪一个
-- int class ==> Integer.class.String.class - Object newInstance(Object...initargs)
--无定长参数,参数类型是Object,传入各种类型都可以 - object.setAccessible(boolean access);
--给予暴力反射获取的构造方法操作权限
--privateConstroctor.setAccessible(true);
成员方法的反射
Method成员方法类
- Method[] getConstructors()
--除了private修饰的方法,其他都可以获取,静态方法也能获取
--继承自Object的方法也能获取 - Method[] getDeclaredConstructors();
--获取类内的所有方法,但是不包括继承而来的方法 - Method method = Class.object.getMethod(String name,Class...paramterTypes);
--getMethod("方法名", 参数);
--paramterTypes不定长参数,传入的的Class对象,是重载的原理 - Method[] getDeclaredMethod()
--获取private修饰的 - invoke(Object obj,Object...args);
--通过反射执行类内的成员方法 - object.setAccessible(boolean access);
--给予暴力反射获取的构造方法操作权限
--privateConstroctor.setAccessible(true);
成员变量的反射
Field
GetClassConstructor:
package d_reflex;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* 通过Class类对象获取当前类的构造方法
* Constructor 构造方法类
*
* 获取Class对象的方式:
推荐用法,最常用用法:
Class.forName("完整的包名.类名");
用来这个方法就不需要导包了
获取非私有化构造函数
获取私有化的构造函数
获取有参数的构造函数
获取无参数的构造函数
*/
public class GetClassConstructor {
public static void main(String[] args) throws ClassNotFoundException,
NoSuchMethodException, SecurityException, InstantiationException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException {
/*
* 【加载】指定类的字节码文件,获取对应的Class对象
*
*/
//获取Class对象
Class cls = Class.forName("d_reflex.Person");//第一个异常:ClassNotFoundException
// Constructor,获取Constructor方法
/*
* Constructor[] getConstructors();
* 获取类内非私有化的构造方法
*/
Constructor[] constructors = cls.getConstructors();// 返回构造方法类对象的数组
for (Constructor constructor : constructors) {
System.out.println(constructor);
// 如果上述参数不存在,会抛出异常
// 抛出异常:java.lang.ClassNotFoundException: reflex.Person
}
/*
* Constructor[] getDeclaredConstructors();
* 暴力反射可以获取私有化构造函数
*/
System.out.println("##########可以获取私有化构造函数");
Constructor[] declaredConstructors = cls.getDeclaredConstructors();
for (Constructor constructor : declaredConstructors) {
System.out.println(constructor);
}
/**
* 根据参数类型来获得对应的构造方法
* Constructor[] getConstructors(Class... parameterTypes);
* 不定长参数列表。不限制参数个数,但是类型必须是Class
* 根据传入的类型,来确定要返回的构造函数是哪一个
* int class ==> Integer.class.String.class
*/
System.out.println("##########获取指定类型的构造函数");
Constructor intConstructor = cls.getConstructor(int.class);
Constructor stringConstructor = cls.getConstructor(String.class);
Constructor bothConstructor = cls.getConstructor(int.class,String.class);
System.out.println(intConstructor);
System.out.println(stringConstructor);
System.out.println(bothConstructor);
/*
* 获取无参构造
*/
System.out.println("##########获取【无参】构造函数");
Constructor privateConstroctor = cls.getDeclaredConstructor(null);
System.out.println(privateConstroctor);
/**
* 此时已经获取Constructor的对象
* 通过Constructor对象,创建一个Person对象
* Object newInstance(Object...initargs)
* 无定长参数,参数类型是Object,传入各种类型都可以
*/
System.out.println("##########通过构造函数类的对象,创建类对象");
Person p = (Person) intConstructor.newInstance(999);
System.out.println(p.getName());
System.out.println(p.getId());
Person p1 = (Person) bothConstructor.newInstance(33,"小明");
System.out.println(p1.getName());
System.out.println(p1.getId());
/*
* 给予暴力反射获取的构造方法操作权限
* object.setAccessible(boolean access);
*/
System.out.println("##########给予暴力反射获取的构造方法操作权限");
privateConstroctor.setAccessible(true);
Person pp = (Person) privateConstroctor.newInstance();
// 无参构造没有值可查看,赋值操作
pp.setId(22);
pp.sleep(8);
pp.setName("大名");
}
}
package d_reflex;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
/**
* 通过Class类对象获取当前类的成员变量
* Field 成员变量类
* @author Administrator
*
*/
public class GetClassField {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException {
// TODO Auto-generated method stub
Class cls = Class.forName("d_reflex.Person");
/*
* Filed[] getFields();
* 返回非私有化成员变量
*/
Field[] fields = cls.getFields();
for (Field field : fields) {
System.out.println(field);
}
System.out.println("#################");
/*
* getDeclaredFields
* 暴力反射,获取私有化
*/
Field[] declaredFields = cls.getDeclaredFields();
for (Field field : declaredFields) {
System.out.println(field);
}
System.out.println("#################");
/*
* Filed getField(String FiledName)
*/
Field afield = cls.getField("test");
System.out.println(afield);
Field bfield = cls.getField("testStatic");
System.out.println(bfield);
/*
* 暴力反射
*/
// Field field = cls.getField("id");
// System.out.println(field);
Field declaredField = cls.getDeclaredField("id");
System.out.println(declaredField);
/*
* set(Object obj,Object value);
* 第一个参数:要操作的当前成员变量对象
* 第二个参数:赋予的数据
*/
System.out.println("########################赋值操作");
Person p = (Person) cls.getConstructor(int.class,String.class).newInstance(1,"类对象");
afield.set(p, 999);
System.out.println(p.getId());
System.out.println(p.getName());
System.out.println(p.test);
//赋予私有化成员变量权限
declaredField.setAccessible(true);
declaredField.set(p, 789);
System.out.println(p.getId());
}
}
package d_reflex;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 通过Class对象获取类内的成员方法
* Method成员方法类
* @author Administrator
*
*/
public class GetClassMethod {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
// Class对象
Class cls = Class.forName("d_reflex.Person");
/*
* Method[] getMethods();
* 除了private修饰的方法,其他都可以获取,静态方法也能获取
* 继承自Object的方法也能获取
*/
Method[] methods = cls.getMethods();
for (Method method : methods) {
// System.out.println(method);
}
System.out.println(methods.length);
/*
* Method[] getDeclaredMethods();
* 获取类内的所有方法,但是不包括继承而来的方法
*/
System.out.println("#####################暴力反射");
Method[] declaredMethods = cls.getDeclaredMethods();
for (Method method : declaredMethods) {
// System.out.println(method);
}
System.out.println(declaredMethods.length);
/*
* 获取指定方法
* Method method = Class.object.getMethod(String name,Class...paramterTypes);
* getMethod("方法名", 参数);
* paramterTypes不定长参数,传入的的Class对象,是重载的原理
*/
Method method1 = cls.getMethod("game", null);
System.out.println("method1:"+method1);
Method method2 = cls.getMethod("game", String.class);
System.out.println("method2:"+method2);
/*
* 获取私有的
* getDeclaredMethod()
* 获取private修饰的
*/
Method privateMethod = cls.getDeclaredMethod("testPrivate", null);
System.out.println(privateMethod);
/*
* 通过反射执行类内的成员方法
* invoke(Object obj,Object...args);
* Object obj:调用该方法的类对象
* Object... args:调用该方法需要的参数
*/
method2.invoke(cls.getConstructor(int.class,String.class).newInstance(1,"小明"),"方法了里ganme");
privateMethod.setAccessible(true);
privateMethod.invoke(cls.getConstructor(int.class,String.class).newInstance(111,"成员"),null);
/*
* 调用静态方法
*/
}
}
package d_reflex;
/**
* 反射:
* 当一个Java文件编译之后生成的.class文件(字节码文件),当这个字节码文件加载到内存,会在内存的【代码区】运行。
* 这个字节码文件,包含了所有的当前对应类的内容。
* Java的反射机制就是根据字节码文件,创建一个Class类对象,通过Class类对象获取在字节码文件中的内容
*
* 【Class对象】包含该字节码文件的所有成员变量(Field),成员方法(Method),构造方法(Constructor)
*
*
*/
public class GetClassObject {
public static void main(String[] args) throws ClassNotFoundException {
// 获取Class对象
/*
* 第一种方法:Class.forname("完整的包名.类名");
* 最常用
* JDBC MyBaits
*/
Class cls1 = Class.forName("d_reflex.Person");
System.out.println(cls1);
/*
* 第二种:类名.class
*/
Class cls2 = Person.class;
System.out.println(cls2);
/*
* 第三种:通过当前类的对象获取Class类对象
* getClass();
*/
Class cls3 = new Person(1,"夏明").getClass();
System.out.println(cls3);
/*
* 三个是否相等:同一个类的Class对象是一样的
*/
System.out.println(cls1==cls2);
System.out.println(cls1==cls3);
System.out.println(cls1==cls3);
}
}
package d_reflex;
public class Person {
private int id;
private String name;
public int test;
public static int testStatic = 10;
private Person() {
super();
}
public Person(int id){
super();
this.id = id;
}
public Person(String name) {
super();
this.name = name;
}
public Person(int id, String name) {
super();
this.id = id;
this.name = name;
}
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 getTest() {
return test;
}
public void setTest(int test) {
this.test = test;
}
public static int getTestStatic() {
return testStatic;
}
public static void setTestStatic(int testStatic) {
Person.testStatic = testStatic;
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", test=" + test + "]";
}
public void sleep(int num){
System.out.println(name+"每天睡"+num+"个小时");
}
public void game(){
System.out.println("ganme()方法执行");
}
public void game(String gname){
System.out.println(this.name+"在玩"+gname);
}
private void testPrivate(){
System.out.println("类内私有化方法");
}
public static void drink(){
System.out.println("喝咖啡");
}
}