反射机制:运行状态中,对于任何一个类(class文件),都知道此类的所有属性和方法;对于任何一个对象,能调用任意一个属性和方法。简言之:动态获取类中信息。
1 反射运行机制
程序首先根据类名得到类名.class文件,然后加载进内存里;创建该字节码文件对象;紧接着创建该字节码内部对应的具体类对象。
2 应用程序如何反射
通过解析.class文件,获取字节码中的对象信息。反射通过Class类完成,该类提供了获取字节码文件中的内容,包括属性(字段)、方法等。
想要对一个类文件进行解剖,只要获得该类的字节码文件对象即可。
3 获取字节码文件对象的三种方法
3.1 利用Object类中的getclass()方法。
以类Car为例,讲述如何获取Car.class字节码文件对象。
Car{
motor;
battery;
Car(){}
show1(){}
show2(){}
}
public static void getClassObject1(){
Car car=new Car();
Class clas=car.getclass();
}//获得Car字节码对象后,clas就可以调用Car类中的属性和方法了。这种方式需要明确具体的类,并创建对象。实际开发中采用较少。
3.2 任何数据类型(基本+引用)都具备静态属性.class来获取对应的class对象。
public static void getClassObject2(){
Class clas=Car.class;
}//同样的效果。这种方式比第一种要高效,但还明确用到类中的静态成员。
3.3 只要通过给定的类名字符串(必须含包名),通过Class.forName(“”)获取类对象。
pubic static void getClassObject3(){
String name="cn.ishuai.viechle.Car";//带包名的类Car
Class clas=Class.forName(name);
}//一样的效果。这种方式只要给出类名,就可获得字节码文件对象,实际开发中最常用。
4 Tomcat如何利用反射进行开发
5 自己实现的反射Demo
具体代码:
package cn.ishuai.viechle;//该包主要实现Car类和Common接口
public class Car {
public String Motor="DO";//发动机类型:柴油缩写DO
public int Battery=2;//蓄电池个数
public Car(){
System.out.println("无参构造函数初始化");
}
public Car(String motor,int battery){
this.Motor=motor;
this.Battery=battery;
System.out.println("含参构造函数初始化");
}
public void show1(){
System.out.println("Motor:"+Motor+" "+"Battery:"+Battery);
}
public void setShow(String moto,int batt){
Motor=moto;
Battery=batt;
System.out.println("Motor:"+moto+" "+"Battery:"+batt);
}
// private void show3(){
// System.out.println("私有方法show3被调用了");
// }
public void useCommon(Common com){
com.open();
com.close();
}
}
----------
package cn.ishuai.viechle;
public interface Common {
public void open();
public void close();
}
package cn.ishuai.reflect;//该包首先用Light和DiDi实现了Common接口。然后通过
import cn.ishuai.viechle.Common;
public class Light implements Common{
@Override
public void open() {
// TODO Auto-generated method stub
System.out.println("车灯亮啦……");
}
@Override
public void close() {
// TODO Auto-generated method stub
System.out.println("车灯关闭……");
}
}
----------
package cn.ishuai.reflect;
import cn.ishuai.viechle.Common;
public class DiDi implements Common {
@Override
public void open() {
// TODO Auto-generated method stub
System.out.println("喇叭响啦……");
}
@Override
public void close() {
// TODO Auto-generated method stub
System.out.println("喇叭停止……");
}
}
----------
package cn.ishuai.reflect;//main文件
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;
import java.lang.reflect.Method;
import cn.ishuai.viechle.Car;
import cn.ishuai.viechle.Common;
public class Test {
public static void getFieldDemo() {
Class clas=Class.forName("cn.ishuai.viechle.Car");
Field fieldMotor=clas.getField("Motor");//只能获取公有的,即使是友元的也获取不到
Field fieldBattery=clas.getField("Battery");
Object obj=clas.newInstance();
fieldMotor.set(obj, "特斯拉");
fieldBattery.set(obj, 10);
Object o1 = fieldMotor.get(obj);
Object o2=fieldBattery.get(obj);
System.out.println("Motor:"+o1+" "+"Battery"+o2);
}
public static void getMethodDemo() throws {
Class clas=Class.forName("cn.ishuai.viechle.Car");
Method method=clas.getMethod("show1", null);
Object obj=clas.newInstance();
method.invoke(obj, null);
}
public static void getMethodDemoParameter(){
Class clas=Class.forName("cn.ishuai.viechle.Car");
Method method=clas.getMethod("setShow", String.class,int.class);
//Constructor cons=clas.getConstructor(String.class,int.class);
Object obj=clas.newInstance();
method.invoke(obj, "小米汽车",8);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Car car=new Car();
//car.setShow("qiyou2",4);//不用new的方式创建新对象
//car.useCommon(new Light());
File configFile = new File("common.propertites");
Properties prop = new Properties();//要熟悉propertites的用法
FileInputStream file = new FileInputStream(configFile);
prop.load(file);//
for(int x=0; x<prop.size(); x++){
String commonName = prop.getProperty("common"+(x+1));
Class clazz = Class.forName(commonName);//用Class去加载这个Common子类,返回common的名字
Common p = (Common) clazz.newInstance();//newInstance()返回的是object,需要强转为接口Common,做参数用
car.useCommon(p);
}
file.close();
//getFieldDemo();
//getMethodDemo();
//getMethodDemoParameter();
//getMethodDemoPrivate();
}
}
可运行代码链接: