在Java中的反射机制中我们可以通过new对象的getClass()方法、类的class属性、Class类的forName()方法获取类的Class对象,再通过该对象创建对象,直接操作程序的内部属性或方法。
测试类:
package nazz.java.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class TestReflect
{
public static void main(String[] args) throws Exception
{
/*
构造方法:
getConstructors:获取目标类的所有公共构造方法
getDeclaredConstructors:获取目标类的所有构造方法
getConstructor:获取单个构造方法,仅对目标类的所有公共构造方法
getDeclaredConstructor:获取单个构造方法,针对目标类的所有构造方法(包含公共构造方法)
仅目标类私有构造方法需要setAccessible(true)
变量:
getFields:获取目标类和父类的所有公共成员变量和静态变量
getDeclaredFields:获取目标类的所有成员变量和静态变量
getField:获取单个变量,仅对目标类和父类所有公共成员变量和静态变量
getDeclaredField:获取单个变量,针对目标类的所有成员变量和静态变量(包含成员变量和静态变量)
仅目标类私有变量需要setAccessible(true)
仅能通过getField获取父类单个公共成员变量和静态变量
方法:
getMethod:获取目标类和父类的所有公共成员方法和静态方法
getDeclaredMethods:获取目标类的所有成员方法和静态方法
getMethod:获取单个方法,仅对目标类和父类所有公共成员方法和静态方法
getDeclaredMethod:获取单个方法,针对目标类的所有成员方法和静态方法(包含成员方法和静态方法)
仅目标类私有方法需要setAccessible(true)
仅能通过getMethod获取父类单个公共成员变量和静态变量
*/
Object instance = null;
Constructor<?> constructor = null;
Class<?> clazz1 = null;
Class<?> clazz2 = null;
Class<?> clazz3 = null;
Field field = null;
Method method = null;
Object result = null;
// 第一种方式获取Class对象
ReflectObject stu1 = new ReflectObject();// 这一new 产生一个Student对象,一个Class对象。
clazz1 = stu1.getClass();// 获取Class对象
System.out.println(clazz1.getName());
// 第二种方式获取Class对象
clazz2 = ReflectObject.class;
System.out.println(clazz2 == clazz1);// 判断第一种方式获取的Class对象和第二种方式获取的是否是同一个
// 第三种方式获取Class对象
try
{
clazz3 = Class.forName("nazz.java.reflect.ReflectObject");// 注意此字符串必须是真实路径,就是带包名的类路径,包名.类名
System.out.println(clazz3 == clazz2);// 判断三种方式是否获取的是同一个Class对象
} catch (ClassNotFoundException e)
{
e.printStackTrace();
}
System.out.println("======================================================================:");
System.out.println();
System.out.println("构造方法获取:");
System.out.println("======================================================================:");
System.out.println("所有公有构造方法:");
Constructor<?>[] conArray = clazz3.getConstructors();
for (Constructor<?> c : conArray)
{
System.out.println(c);
}
System.out.println("======================================================================:");
System.out.println("所有的构造方法(包括:私有、受保护、默认、公有):");
conArray = clazz3.getDeclaredConstructors();
for (Constructor<?> c : conArray)
{
System.out.println(c);
}
System.out.println("======================================================================:");
System.out.println("获取公有、无参的构造方法:");
constructor = clazz3.getConstructor();
System.out.println(constructor);
System.out.println("======================================================================:");
System.out.println("获取非公有的构造方法:");
constructor = clazz3.getDeclaredConstructor(int.class);
System.out.println(constructor);
// 私有构造器需要暴力访问(忽略掉访问修饰符)
constructor.setAccessible(true);
instance = constructor.newInstance(18);
System.out.println();
System.out.println("变量获取:");
System.out.println("======================================================================:");
//2.获取变量
System.out.println("获取所有公有的变量:");
Field[] fieldArray = clazz3.getFields();
for(Field f : fieldArray){
System.out.println(f);
}
System.out.println("======================================================================:");
System.out.println("获取所有的变量(包括私有、受保护、默认的):");
fieldArray = clazz3.getDeclaredFields();
for(Field f : fieldArray){
System.out.println(f);
}
System.out.println();
System.out.println("子类成员变量获取:");
System.out.println("======================================================================:");
instance = clazz3.getConstructor().newInstance();//产生Student对象--》Student stu = new Student();
System.out.println("获取公有子类成员变量并调用:");
field = clazz3.getField("name");
System.out.println(field);
//为变量设置值
field.set(instance, "刘德华");
//获取设置的值
System.out.println(field.get(instance));
System.out.println("======================================================================:");
System.out.println("获取受保护子类成员变量并调用:");
field = clazz3.getDeclaredField("age");
System.out.println(field);
field.setAccessible(true);
//为变量设置值
field.set(instance, "18");
//获取设置的值
System.out.println(field.get(instance));
System.out.println("======================================================================:");
System.out.println("获取默认子类成员变量并调用:");
field = clazz3.getDeclaredField("sex");
System.out.println(field);
field.setAccessible(true);
//为变量设置值
field.set(instance, '男');
//获取设置的值
System.out.println(field.get(instance));
System.out.println("======================================================================:");
System.out.println("获取私有子类成员变量并调用:");
field = clazz3.getDeclaredField("phoneNum");
System.out.println(field);
field.setAccessible(true);
//为变量设置值
field.set(instance, "15815541622");
//获取设置的值
System.out.println(field.get(instance));
System.out.println();
System.out.println("父类成员变量获取:");
System.out.println("======================================================================:");
instance = clazz3.getConstructor().newInstance();//产生Student对象--》Student stu = new Student();
System.out.println("获取公有父类成员变量并调用:");
field = clazz3.getField("parentName");
System.out.println(field);
//为变量设置值
field.set(instance, "刘德华");
//获取设置的值
System.out.println(field.get(instance));
System.out.println();
System.out.println("静态变量获取:");
System.out.println("======================================================================:");
instance = clazz3.getConstructor().newInstance();//产生Student对象--》Student stu = new Student();
System.out.println("获取公有静态变量并调用:");
field = clazz3.getField("staticName");
System.out.println(field);
//为变量设置值
field.set(null, "刘德华");
//获取设置的值
System.out.println(field.get(instance));
System.out.println("======================================================================:");
System.out.println("获取受保护静态变量并调用:");
field = clazz3.getDeclaredField("staticAge");
System.out.println(field);
field.setAccessible(true);
//为变量设置值
field.set(null, "18");
//获取设置的值
System.out.println(field.get(instance));
System.out.println("======================================================================:");
System.out.println("获取默认静态变量并调用:");
field = clazz3.getDeclaredField("staticSex");
System.out.println(field);
field.setAccessible(true);
//为变量设置值
field.set(null, '男');
//获取设置的值
System.out.println(field.get(instance));
System.out.println("======================================================================:");
System.out.println("获取私有静态变量并调用:");
field = clazz3.getDeclaredField("staticPhoneNum");
System.out.println(field);
field.setAccessible(true);
//为变量设置值
field.set(null, "15815541622");
//获取设置的值
System.out.println(field.get(instance));
System.out.println();
System.out.println("父类静态变量获取:");
System.out.println("======================================================================:");
instance = clazz3.getConstructor().newInstance();//产生Student对象--》Student stu = new Student();
System.out.println("获取公有静态变量并调用:");
field = clazz3.getField("staticParentName");
System.out.println(field);
//为变量设置值
field.set(null, "刘德华");
//获取设置的值
System.out.println(field.get(instance));
// =====================================================================================================
System.out.println();
System.out.println("方法获取:");
System.out.println("======================================================================:");
System.out.println("获取所有的”公有“方法:");
clazz3.getMethods();
Method[] methodArray = clazz3.getMethods();
for(Method m : methodArray){
System.out.println(m);
}
System.out.println("======================================================================:");
System.out.println("获取所有的方法,包括私有的:");
methodArray = clazz3.getDeclaredMethods();
for(Method m : methodArray){
System.out.println(m);
}
System.out.println();
System.out.println("成员方法:");
System.out.println("======================================================================:");
System.out.println("获取公有的show1()方法:");
method = clazz3.getMethod("show1", String.class);
System.out.println(method);
result = method.invoke(instance, "刘德华");
System.out.println("返回值:" + result);
System.out.println("======================================================================:");
System.out.println("获取受保护show2()方法:");
method = clazz3.getDeclaredMethod("show2");
System.out.println(method);
result = method.invoke(instance);
System.out.println("返回值:" + result);
System.out.println("======================================================================:");
System.out.println("获取默认的show3()方法:");
method = clazz3.getDeclaredMethod("show3");
System.out.println(method);
result = method.invoke(instance);
System.out.println("返回值:" + result);
System.out.println("======================================================================:");
System.out.println("获取私有的show4()方法:");
method = clazz3.getDeclaredMethod("show4", int.class);
System.out.println(method);
method.setAccessible(true);//解除私有限定
result = method.invoke(instance, 20);//需要两个参数,一个是要调用的对象(获取有反射),一个是实参
System.out.println("返回值:" + result);
System.out.println();
System.out.println("父类成员方法:");
System.out.println("======================================================================:");
System.out.println("获取公有的parentShow1()方法:");
method = clazz3.getMethod("parentShow1", String.class);
System.out.println(method);
result = method.invoke(instance, "刘德华");
System.out.println("返回值:" + result);
System.out.println();
System.out.println("静态方法:");
System.out.println("======================================================================:");
System.out.println("获取公有的staticShow1()方法:");
method = clazz3.getMethod("staticShow1", String.class);
System.out.println(method);
result = method.invoke(null, "刘德华");
System.out.println("静态返回值:" + result);
System.out.println("======================================================================:");
System.out.println("获取受保护的staticShow2()方法:");
method = clazz3.getDeclaredMethod("staticShow2");
System.out.println(method);
result = method.invoke(null);
System.out.println("静态返回值:" + result);
System.out.println("======================================================================:");
System.out.println("获取默认的staticShow3()方法:");
method = clazz3.getDeclaredMethod("staticShow3");
System.out.println(method);
result = method.invoke(null);
System.out.println("静态返回值:" + result);
System.out.println("======================================================================:");
System.out.println("获取私有的staticShow1()方法:");
method = clazz3.getDeclaredMethod("staticShow4", int.class);
System.out.println(method);
method.setAccessible(true);//解除私有限定
result = method.invoke(null, 20);//需要两个参数,一个是要调用的对象(获取有反射),一个是实参
System.out.println("静态返回值:" + result);
System.out.println();
System.out.println("父类静态方法:");
System.out.println("======================================================================:");
System.out.println("获取公有的staticstaticParentShow1()方法:");
method = clazz3.getMethod("staticstaticParentShow1", String.class);
System.out.println(method);
result = method.invoke(null, "刘德华");
System.out.println("静态返回值:" + result);
}
}
测试子类:
package nazz.java.reflect;
import java.io.Serializable;
public class ReflectObject extends ReflectObjectParent implements Serializable
{
private static final long serialVersionUID = 1L;
public String name;
protected String age;
char sex;
private String phoneNum;
public static String staticName;
protected static String staticAge;
static char staticSex;
private static String staticPhoneNum;
@Override
public String toString()
{
return "ReflectObject [name=" + name + ", age=" + age + ", sex=" + sex + ", phoneNum=" + phoneNum + "]";
}
// ---------------构造方法-------------------
// (默认的构造方法)
ReflectObject(String name)
{
System.out.println("调用了String参数的默认构造方法 name = " + name);
}
// 无参构造方法
public ReflectObject()
{
System.out.println("调用了无参的默认构造方法");
}
// 受保护的构造方法
protected ReflectObject(boolean n)
{
System.out.println("受保护的构造方法 n = " + n);
}
// 私有构造方法
private ReflectObject(int age)
{
System.out.println("私有的构造方法 年龄:" + age);
}
// **************成员方法***************//
public String show1(String s)
{
System.out.println("调用了成员方法:公有的,String参数的show1(): s = " + s);
return "show1";
}
protected String show2()
{
System.out.println("调用了成员方法:受保护的,无参的show2()");
return "show2";
}
String show3()
{
System.out.println("调用了成员方法:默认的,无参的show3()");
return "show3";
}
private String show4(int age)
{
System.out.println("调用了成员方法,私有的,int参数的show4(): age = " + age);
return "show4";
}
// **************静态方法***************//
public static String staticShow1(String s)
{
System.out.println("调用了静态方法:公有的,String参数的staticShow1(): s = " + s);
return "staticShow1";
}
protected static String staticShow2()
{
System.out.println("调用了静态方法:受保护的,无参的staticShow2()");
return "staticShow2";
}
static String staticShow3()
{
System.out.println("调用了静态方法:默认的,无参的staticShow3()");
return "staticShow3";
}
private static String staticShow4(int age)
{
System.out.println("调用了静态方法,私有的,int参数的staticShow4(): age = " + age);
return "staticShow4";
}
}
测试父类:
package nazz.java.reflect;
import java.io.Serializable;
public class ReflectObjectParent implements Serializable
{
private static final long serialVersionUID = 1L;
public String parentName;
protected String parentAge;
char parentSex;
private String parentPhoneNum;
public static String staticParentName;
protected static String staticParentAge;
static char staticParentSex;
private static String staticParentPhoneNum;
// ---------------构造方法-------------------
@Override
public String toString()
{
return "ReflectObjectParent [parentName=" + parentName + ", parentAge=" + parentAge + ", parentSex="
+ parentSex + ", parentPhoneNum=" + parentPhoneNum + "]";
}
// (默认的构造方法)
ReflectObjectParent(String name)
{
System.out.println("调用了String参数的默认构造方法 name = " + name);
}
// 无参构造方法
public ReflectObjectParent()
{
System.out.println("调用了无参的默认构造方法");
}
// 受保护的构造方法
protected ReflectObjectParent(boolean n)
{
System.out.println("受保护的构造方法 n = " + n);
}
// 私有构造方法
private ReflectObjectParent(int age)
{
System.out.println("私有的构造方法 年龄:" + age);
}
// **************成员方法***************//
public String parentShow1(String s)
{
System.out.println("调用了成员方法:公有的,String参数的parentShow1(): s = " + s);
return "parentShow1";
}
protected String parentShow2()
{
System.out.println("调用了成员方法:受保护的,无参的parentShow2()");
return "parentShow2";
}
String parentShow3()
{
System.out.println("调用了成员方法:默认的,无参的parentShow3()");
return "parentShow3";
}
private String parentShow4(int age)
{
System.out.println("调用了成员方法,私有的,int参数的parentShow4(): age = " + age);
return "parentShow4";
}
// **************静态方法***************//
public static String staticstaticParentShow1(String s)
{
System.out.println("调用了静态方法:公有的,String参数的staticParentShow1(): s = " + s);
return "staticParentShow1";
}
protected static String staticParentShow2()
{
System.out.println("调用了静态方法:受保护的,无参的staticParentShow2()");
return "staticParentShow2";
}
static String staticParentShow3()
{
System.out.println("调用了静态方法:默认的,无参的staticParentShow3()");
return "staticParentShow3";
}
private static String staticParentShow4(int age)
{
System.out.println("调用了静态方法,私有的,int参数的staticParentShow4(): age = " + age);
return "staticParentShow4";
}
}
构造方法:
- getConstructors:获取目标类的所有公共构造方法
- getDeclaredConstructors:获取目标类的所有构造方法
- getConstructor:获取单个构造方法,仅对目标类的所有公共构造方法
- getDeclaredConstructor:获取单个构造方法,针对目标类的所有构造方法(包含公共构造方法)
- 仅目标类私有构造方法需要setAccessible(true)
变量:
- getFields:获取目标类和父类的所有公共成员变量和静态变量
- getDeclaredFields:获取目标类的所有成员变量和静态变量
- getField:获取单个变量,仅对目标类和父类所有公共成员变量和静态变量
- getDeclaredField:获取单个变量,针对目标类的所有成员变量和静态变量(包含成员变量和静态变量)
- 仅目标类私有变量需要setAccessible(true)
- 仅能通过getField获取父类单个公共成员变量和静态变量
方法:
- getMethod:获取目标类和父类的所有公共成员方法和静态方法
- getDeclaredMethods:获取目标类的所有成员方法和静态方法
- getMethod:获取单个方法,仅对目标类和父类所有公共成员方法和静态方法
- getDeclaredMethod:获取单个方法,针对目标类的所有成员方法和静态方法(包含成员方法和静态方法)
- 仅目标类私有方法需要setAccessible(true)
- 仅能通过getMethod获取父类单个公共成员变量和静态变量