Reflect
常规实例化对象:
类——->对象
eg.
Object c=new Object();
反射:
对象——–>类
反射则是从一个对象获取到类的内容。
可以说反射机制可以暴力破解面向对象的封装性!!!
(也就是说我可以通过这个对象得到其他类里的private属性、private方法)
在反射机制里所说的这个对象并非普通的对象,而是一个特殊类的对象,而这个类就是——–Class类
通俗来说,
一堆狗在一块儿,提取出它们的共同特征可以形成一个 Dog类
一堆人在一块儿,提取出他们的共同特征可以形成一个 Person类。
那么,一堆类在一块儿,提取出它们的共同特征就形成了——-Class类。
可能有人会问,类有什么共同特征?
当然有,它们都有属性,构造方法,类里面的方法呀。
除了Class类的对象外,我们还要用到一些东西:
java.lang.reflect.*
import java.lang.reflect.Constructor;
//获取构造方法
import java.lang.reflect.Field;
//获取属性
import java.lang.reflect.InvocationTargetException;
//一些异常抛出
import java.lang.reflect.Method;
//获取方法
import java.lang.reflect.Modifier;
//获取修饰符(toString方法将返回的数字转为对应修饰符)
回归正题,Class类的对象怎样能够得到其他类里面的东西呢?咱们一步一步来说。
首先要创建Class类的对象
/**
* 创建ClassL类对象
* 有三种方法
*/
public static void test1()
{
//类.class
Class personClass=Person.class;
//Class.forName方法
try {
Class personClass1=Class.forName("ReflectTest.Person");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//通过对象的getClass方法
Person person=new Person();
Class personClass2=person.getClass();
}
同时我们也可以通过Class类对象,对类进行实例化
/**
* 通过Class对象实例化目标类的对象
*/
public static void test2()
{
Class personClass=Person.class;
try {
Person person=(Person)personClass.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
根据Class类对象获取到类的构造方法
/**
* 获取类的构造方法
*/
public static void test3()
{
Class personClass=Person.class;
//获取所有的构造方法
Constructor[] constructors=personClass.getConstructors();
for(int i=0;i<constructors.length;i++)
{
System.out.println(constructors[i].getName());
System.out.println(constructors[i].getParameterTypes());
}
System.out.println("-------------------------------");
try {
Constructor<Person> constructor=personClass.getConstructor(String.class,int.class,String.class);
constructor.newInstance("李明",21,"男");
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
获取类的所有属性
/**
* 获得类的所有属性
*/
public static void test4()
{
Class personClass=Person.class;
//获取所有非私有属性
Field[] fields=personClass.getFields();
System.out.println(fields.length);
//获取所有属性
Field[] declaredFields=personClass.getDeclaredFields();
System.out.println(declaredFields.length);
for(int i=0;i<declaredFields.length;i++)
{
int modifiers=declaredFields[i].getModifiers();
System.out.println(Modifier.toString(modifiers)+" "
+declaredFields[i].getName()+" "
+declaredFields[i].getType());
}
}
获取类的包名
/**
* 获取类的包名
*/
public static void test5()
{
Class personClass=Person.class;
Package package1=personClass.getPackage();
System.out.println("包名为: "+package1);
}
获取类的所有方法,并且可以通过该类的实例化对象调用这些方法
/**
* 获取类的方法
* 通过实例对象来调用类中的方法
*/
public static void test6()
{
Class personClass=Person.class;
//获取所有公有的方法(包括继承的父类的方法)
Method[] methods=personClass.getMethods();
for(int i=0;i<methods.length;i++)
{
System.out.println(methods[i]);
}
//调用公有的方法
System.out.println("调用公有的方法");
Person person=new Person("狗子", 21, "未知");
for(int i=0;i<methods.length;i++)
{
if(methods[i].getName().equals("toString"))
{
try {
String a=(String) methods[i].invoke(person);
System.out.println(a);
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//获取所有方法(包括私有方法,但是只包括当前类,没有父类的方法)
System.out.println("获取所有的方法:");
Method[] methods1=personClass.getDeclaredMethods();
for(int i=0;i<methods1.length;i++)
{
System.out.println(methods1[i]);
}
System.out.println("调用私有方法");
for(int i=0;i<methods1.length;i++)
{
if(methods1[i].getName().equals("PrivateMethod"))
{
//暴力设置私有方法可用
methods1[i].setAccessible(true);
try {
methods1[i].invoke(person);
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}