------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
反射
一、概述
反射技术:
Java反射机制是在运行状态中,对于任意一个类(class文件),都能够知道这个类中的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
二、反射的基础Clsss类
获取Class对象的三种方式
方式一:
通过对象的getClass方法进行获取。
如:Class clazz=new Person().getClass();//Person是一个类名
弊端:每次都需要具体的类和该类的对象,以及调用getClass方法。
方式二:
任何数据类型都具备着一个静态的属性class,这个属性直接获取到该类型的对应Class对象。
如:Class clazz=Person.class;//Person是一个类名
比第一种较为简单,不用创建对象,不用调用getClass方法,但是还是要使用具体的类,和该类中的一个静态属性class完成。
方式三:
这种方式较为简单,只要知道类的名称即可。不需要使用该类,也不需要去调用具体的属性和行为。就可以获取到Class对象了。
如:Class clazz=Class.forName("包名.Person");//Person是一个类名
这种方式仅知道类名就可以获取到该类字节码对象的方式,更有利于扩展。
package cn.itcast.bean;
public class Person//Person类
{
private int age;
private String name;
public Person(int age,String name){
super();
this.age = age;
this.name = name;
System.out.println("Person param run..." + this.name + ":" + this.age);
}
public Person(){
super();
System.out.println("person run");
}
public void show(){
System.out.println(name + "...show run..." + age);
}
private void privateMethod(){
System.out.println("method run");
}
public void paramMethod(String str,int num){
System.out.println("paramMethod run..." + str + ":" + num);
}
public static void staticMethod(){
System.out.println("static method run...");
}
}
练习:获取字节码对象的三种方式:
import cn.itcast.bean.Person;
//要想要对字节码文件进行解剖,必须要有字节码文件对象。
public class ReflectDemo
{
public static void main(String[] args) throws ClassNotFoundException {
getClassObject_1();
System.out.println("--------------------");
getClassObject_2();
System.out.println("--------------------");
getClassObject_3();
}
// 方式一:Object类中的getClass()方法的。
public static void getClassObject_1(){
Person p = new Person();
Class clazz = p.getClass();
Person p1 = new Person();
Class clazz1 = p1.getClass();
System.out.println(clazz == clazz1);
}
/*
* 方式二:任何数据类型都具备一个静态的属性.class来获取其对应的Class对象。
public static void getClassObject_2(){
Class clazz = Person.class;
Class clazz1 = Person.class;
System.out.println(clazz == clazz1);
}
//方式三
public static void getClassObject_3() throws ClassNotFoundException {
//可以把类的字符串名称写到配置文件中,然后读取出来。
String className = "cn.itcast.bean.Person";
Class clazz = Class.forName(className);
System.out.println(clazz);
}
}
二、Constructor类
获取构造方法:
1)得到这个类的所有构造方法:如得到上面示例中Person类的所有构造方法
Constructor[] cons = Class.forName(“cn.itheima.Person”).getConstructors();
2)获取某一个构造方法:
Constructor con=Person.class.getConstructor(String.class,int.class);
import cn.itcast.bean.Person;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class ReflectDemo
{
public static void main(String[] args) throws Exception {
createNewObject_1();
System.out.println("--------------------");
createNewObject_2();
}
public static void createNewObject_1() throws ClassNotFoundException,InstantiationException,IllegalAccessException {
String name = "cn.itcast.bean.Person";
//找寻该文件类文件,并加载进内存,并产生Class对象。
Class clazz = Class.forName(name);
//如何产生该类的对象呢?
Object obj = clazz.newInstance();//调用Person的空参构造函数
}
public static void createNewObject_2() throws ClassNotFoundException,InstantiationException,NoSuchMethodException,IllegalAccessException,InvocationTargetException {
//Person p = new Person("小强",39);
String name = "cn.itcast.bean.Person";
//找寻该名称类文件,并加载进内存,并产生Class对象。
Class clazz = Class.forName(name);
//获取到了指定的构造函数对象
Constructor constructor = clazz.getConstructor(int.class,String.class);
//通过该构造器对象的newInstance方法进行对象的初始化。
Object obj = constructor.newInstance(38,"小明");
}
}
三、Field类
1、Field类代表某个类中一个成员变量
2、方法
Field getField(String s);//只能获取公有和父类中公有
Field getDeclaredField(String s);//获取该类中任意成员变量,包括私有
setAccessible(ture); //如果是私有字段,要先将该私有字段进行取消权限检查的能力。也称暴力访问。
set(Object obj, Object value);//将指定对象变量上此Field对象表示的字段设置为指定的新值。
Object get(Object obj);//返回指定对象上Field表示的字段的值。
示例:
import cn.itcast.bean.Person;
import java.lang.reflect.Field;
public class ReflectDemo
{
public static void main(String[] args) throws Exception {
getFieldDemo();
}
/*
* 获取字节码文件中的字段。
*/
public static void getFieldDemo() throws Exception {
Class clazz = Class.forName("cn.itcast.bean.Person");
//getField只能获取所有可访问公共字段,private获取不到。
//Field field = claszz.getField("age");
//getDeclaredField可以获取到公共字段,也可以获取到私有字段。
Field field = clazz.getDeclaredField("age");
//对私有字段的访问取消权限检查,暴力访问。
field.setAccessible(true);
Object obj = clazz.newInstance();
//为对象的属性赋值
field.set(obj,89);
//获取某对象的某属性值
Object o = field.get(obj);
System.out.println(field);
}
}
四、Method类
方法
Method[] getMethods();//只获取公共和父类中的方法。
Method[] getDeclaredMethods();//获取本类中包含私有。
Method getMethod("方法名",参数.class(如果是空参可以写null));
Object invoke(Object obj ,参数);//调用方法
如果方法是静态,invoke方法中的对象参数可以为null。
import cn.itcast.bean.Person;
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
public class ReflectDemo
{
public static void main(String[] args) throws Exception {
getMethodDemo_1();
System.out.println("---------------------------");
getMethodDemo_2();
System.out.println("---------------------------");
getMethodDemo_3();
}
/*
* 获取指定Class中的公共函数。
*/
public static void getMethodDemo_1() throws Exception {
Class clazz = Class.forName("cn.itcast.bean.Person");
Method[] methods = clazz.getMethods();//获取的都是公有的方法
methods = clazz.getDeclaredMethods();//只获取本类中所有方法,包括私有。
for(Method method : methods){
System.out.println(method);
}
}
public static void getMethodDemo_2() throws Exception {
Class clazz = Class.forName("cn.itcast.bean.Person");
Method method = clazz.getMethod("show",null);//获取空参数一般方法
Object obj = clazz.newInstance();
Constructor constructor = clazz.getConstructor(int.class,String.class);
obj = constructor.newInstance(37,"张三");
method.invoke(obj,null);
}
public static void getMethodDemo_3() throws Exception {
Class clazz = Class.forName("cn.itcast.bean.Person");
Method method = clazz.getMethod("paramMethod",String.class,int.class);//获取空参数一般方法
Object obj = clazz.newInstance();
Constructor constructor = clazz.getConstructor();
obj = constructor.newInstance();
method.invoke(obj,"李四",89);
}
}