Java基础---反射

来源:互联网 发布:俄罗斯美女知乎 编辑:程序博客网 时间:2024/06/17 00:25
反射

Java反射机制是在运行状态,对于任意一个类(class文件),都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象方法功能称为java语言反射机制。

P.S.

所谓的框架就是对外提供一些接口,也就是功能扩展的标准,由实现按照这个接口标准实现。框架累不如果需要操纵这些实现类的对象完成某些操作,那么只需要把这些类的全名(包名+类名)写在某个配置文件中,框架代码只需要读取这个配置文件,就可以获取这个实现类的字节码文件,然后利用反射技术创建这个实现类的对象并且调用相应的方法完成一些操作

用于描述字节码的类就是Class类,创建对象,可以取字节码文件的内容,如字段、构造函数、一般函数。该类就可以获取字节码文件中的所有内容,那么反射就是依靠该类完成的。想要对一个类文件进行破解,只要获取该类的字节码文件对象即可。

示例:获取字节码文件对象的3种方式

Person.java

package cn.itcast.bean;public class Person {private int age;private String name;public Person(int age,String name){this.age=age;this.name=name;System.out.println("Person param run..."+this.name+":"+this.age);;}public Person(){System.out.println("Person run");}public void show(){System.out.println(name+"...show method run"+age);}private void privateMethod(){System.out.println("private 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...");}}
ReflectDemo.java
import cn.itcast.bean.Person;public class RefectDemo {public static void main(String[] args) throws ClassNotFoundException {// TODO Auto-generated method stubgetClassObject_1();System.out.println("--------------");getClassOjbect_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 getClassOjbect_2(){Class clazz = Person.class;Class clazz1 = Person.class;System.out.println(clazz==clazz1);}/* * 方式三:只要通过给定的类字符串名称就可以获取该类,更为扩展。 * 可以用Class类中的方法完成。 * 该方法就是forName. * 这种方法只要名称即可,更为扩展,扩展性更强。 * */public static void getClassObject_3() throws ClassNotFoundException{//可以把类的字符串名称写到配置文件中,然后读取出来。String className = "cn.itcast.bean.Person";Class clazz = Class.forName(className);System.out.println(clazz);}}

示例:获取Class中的构造函数
import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;public class RefectDemo {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {// TODO Auto-generated method stubcreateNewObject_1();System.out.println("--------------");createNewObject_2();}public static void createNewObject_1() throws ClassNotFoundException, InstantiationException, IllegalAccessException{//早期:new时候,先根据被new的类名寻找该类的字节码文件,并加载进内存,//并创建该字节码文件对象,并接着创建该字节文件的对应的Person对象。//Person p = new Person();//现在:String name = "cn.itcast.bean.Person";//寻找创建该字节码文件对象,并接着创建字节文件的对应的Person对象。Class clazz = Class.forName(name);//产生对象Object obj = clazz.newInstance();//调用Person的空参数构造函数}public static void createNewObject_2() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{//Person p = new Person("小明",36);/* * 当获取指定名称对应类中所体现的对象时。 * 而该对象初始化不使用空参数的构造函数。 * 既然是通过指定的构造函数进行对象初始化。 * 所以应该先获取到该构造函数,通过字节码文件对象即可完成。 * 该方法是:getConstructor(parameterTypes); * */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(35,"小红");}}

示例:获取Class中的字段

import java.lang.reflect.Field;public class RefectDemo {public static void main(String[] args) throws Exception{ // TODO Auto-generated method stubgetFiedDemo();}public static void getFiedDemo() throws ClassNotFoundException, NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException{Class clazz = Class.forName("cn.itcast.bean.Person");//getFiel只能获取所有可访问公共字段,private获取不到。//Field filed = clazz.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+":"+o);}}

示例:获取Class中的方法

import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;public class RefectDemo {public static void main(String[] args) throws Exception{ // TODO Auto-generated method stubgetMethodDemo_1();System.out.println("---------");getMethodDemo_2();System.out.println("----------");getMethodDemo_3();}public static void getFiedDemo() throws ClassNotFoundException, NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException{Class clazz = Class.forName("cn.itcast.bean.Person");//getFiel只能获取所有可访问公共字段,private获取不到。//Field filed = clazz.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+":"+o);}/* * 获取指定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);//获取空参数一般方法Constructor constructor = clazz.getConstructor(int.class,String.class);Object obj = constructor.newInstance(36,"小红");//实例化有参数的构造函数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();//实例化无参的构造函数method.invoke(obj, "小强",99);}}

反射练习

PCI.java

package cn.itcast.reflect.test;public interface PCI {public void open();public void close();}
SoundCard.java
package cn.itcast.reflect.test;public class SoundCard implements PCI {@Overridepublic void open() {System.out.println("sound open");}@Overridepublic void close() {System.out.println("sound close");}}
NetCard.java
package cn.itcast.reflect.test;public class NetCard implements PCI {@Overridepublic void open() {// TODO Auto-generated method stubSystem.out.println("net card open");}@Overridepublic void close() {// TODO Auto-generated method stubSystem.out.println("net card close");}}
Mainboard.java
package cn.itcast.reflect.test;public class Mainboard {public void run(){System.out.println("main board run...");}public void usePCI(PCI p){if(p!=null){p.open();p.close();}}}
pci.Properties文件
pci1=cn.itcast.reflect.test.NetCardpci2=cn.itcast.reflect.test.SoundCard
ReflectTest.java
import java.io.File;import java.io.FileInputStream;import java.util.Properties;import cn.itcast.reflect.test.Mainboard;import cn.itcast.reflect.test.PCI;public class ReflectTest {public static void main(String[] args) throws Exception {// TODO Auto-generated method stubMainboard mb = new Mainboard();mb.run();File configFile = new File("pci.properties");Properties prop = new Properties();FileInputStream fis = new FileInputStream(configFile);prop.load(fis);for (int i = 0; i < prop.size(); i++) {String pciName = prop.getProperty("pci"+(i+1));Class clazz = Class.forName(pciName);PCI p = (PCI)clazz.newInstance();mb.usePCI(p);}fis.close();}}

0 0
原创粉丝点击