1.什么是反射?
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
通俗来说,反射机制就是可以把一个类,类的成员(函数,属性),当成一个对象来操作,也就是说,类,类的成员,我们在运行的时候还可以动态地去操作他们。
2.为什么需要反射?
反射能够让我们:
(1)在运行时检测对象的类型;
(2)动态构造某个类的对象;
(3)检测类的属性和方法;
(4)任意调用对象的方法;
(5)修改构造函数、方法、属性的可见性;
反射是框架中常用的方法。
3.demo
(1)反射获取field
package reflection;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class GetFieldsFromReflection {
/**通过反射去获取类的私有属性和访问私有方法
* @param args
* @throws NoSuchFieldException
* @throws SecurityException
*/
public static void main(String[] args) throws SecurityException, NoSuchFieldException {
try {
Class<?> clazz = Class.forName("reflection.Person");//jvm加载类
Object obj = clazz.newInstance();//实例化
Person person = (Person)obj;
//获取字段值,第一种:通过构造getter方法,然后使用method.invoke(object instance)获取
Field[] fields = clazz.getDeclaredFields();//for all fields
for (Field field : fields) {
System.out.print(field.getName() + ":");
//System.out.println(p.getName());
String getter = "get" + field.getName().substring(0,1).toUpperCase() + field.getName().toString().substring(1);//构造getter方法名称
Method m = clazz.getMethod(getter, new Class[0]);//获取字段值
System.out.println(m.invoke(person));
System.out.println(m.getReturnType());
System.out.println(m.getReturnType().getSimpleName());
System.out.println("-------------------------");
}
//获取字段值,第二种:通过类field获取,field.get(object instance),若是静态变量,则field.get(object)或者field.get(object instance)
Field fil0 = clazz.getField("sex");
System.out.println("第二种获取field方法:" + fil0.get( person));//非static变量通过类实例获取
Field fil1 = clazz.getField("staticSex");
System.out.println("第二种获取field方法(static变量):" + fil1.get( clazz));//static变量直接通过类获取
//获取字段类型
Field fil2 = clazz.getField("sex");
System.out.println("字段类型是:" + fil2.getType());
//getFields for accessible public fields
Field[] fils = clazz.getFields();
for(Field field : fils){
System.out.println("-------------" + field + "------------------");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
class Person{
private String name = "lopez";
private String age = "23";
public String sex="male";
public static String staticSex = "fmale";
public static String getStaticSex() {
return staticSex;
}
public static void setStaticSex(String staticSex) {
Person.staticSex = staticSex;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public void getMessage(){
System.out.println("name:" + name + "age:" + age);
}
private void getPrivateData(){
System.out.println("name:lopez,passWord:123456");
}
}
(2).反射获取method
package reflection;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class GetMethodFromReflection {
/**
* @param args
*/
public static void main(String[] args) {
try {
Class<?> clazz = Class.forName("reflection.HiWord");
Object o = clazz.newInstance();
//无参方法调用
Method m = clazz.getMethod("getWord", null);
m.invoke(o, null);
//有参方法调用
Method m1 = clazz.getMethod("getBook", String.class);
m1.invoke(o, "MyParameter");
//多参方法
Method m2 = clazz.getMethod("getWatch", String.class,String.class,int.class);
m2.invoke(o, "MyParameter1","MyParameter2",3);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
class HiWord{
public HiWord(){//构造方法
}
public void getWord(){//无参方法
System.out.println("这是一个无参方法!");
}
public void getBook(String str){//有参方法
System.out.println("这是一个有参方法,参数为:" + str);
}
public void getWatch(String str,String str1,int str2){//有参方法
System.out.println("这是一个有参方法,参数分别为:" + str + "," + str1 +"," +str2 + "");
}
}
(3)反射获取构造器
package reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class GetConstructorAndCreateInstance {
/**reflection constructor
* @author lilewen
* @param args
*/
public static void main(String[] args) {
try {
Class<?> clazz = Class.forName("reflection.HelloWord2");//jvm加载类(Class<?>为未知类)
Constructor<?>[] constructor = clazz.getConstructors();
//获取构造器参数类型
Class<?>[] paraeterType0s = constructor[0].getParameterTypes();//null
Class<?>[] paraeterType1s = constructor[1].getParameterTypes();//class java.lang.String
for (Class<?> class1 : paraeterType1s) {
if(class1 != null){
System.out.println(class1.getSimpleName());
}
}
//调用构造器生成实例
HelloWord2 helloWord2 = (HelloWord2) constructor[0].newInstance();
HelloWord2 helloWord21 = (HelloWord2) constructor[1].newInstance("abc");
helloWord2.print();
helloWord21.print();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
class HelloWord2{
String s = null;
public HelloWord2(){};
public HelloWord2(String s){
this.s = s;
}
public void print(){
System.out.println(s);
}
}
(4)反射访问私有属性
package reflection;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class AccessPrivateFromReflection {
/**
* @param args
*/
public static void main(String[] args) {
try {
Class<?> clazz = Class.forName("reflection.Person1");
Object o = clazz.newInstance();
//访问私有变量
Field[] fields = clazz.getDeclaredFields();//获取私有变量getDeclaredFields
//Field[] fils = o.getClass().getFields();只能获取public变量
for(Field field : fields){
field.setAccessible(true);//必须设置为可访问
System.out.println(field.get(o));
}
//访问私有方法
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
method.setAccessible(true);
method.invoke(o,null);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
class Person1{
private String name = "lopez";
private String password = "123456";
public String age = "23";
private String Method1(){
System.out.println("私有方法能够被访问!");
return "OK";
}
}