黑马程序员——java基础——反射机制的学习

来源:互联网 发布:最新网络语 编辑:程序博客网 时间:2024/06/05 15:55

android培训java培训期待与您交流!

一、反射的概念

主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。
反射是java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接。但是反射使用不当会成本很高!

二、反射的作用:
1、反编译:.class-->.java
2、通过反射机制访问对象的属性,方法,构造方法等,不仅仅可以是访问公共的还可以访问私有权限修饰符修饰的属性,方法,构造方法;

三、SUN公司为我们提供了反射机制中的类:
java.lang.Class;           
java.lang.reflect.Constructor;
java.lang.reflect.Field;        
java.lang.reflect.Method;
java.lang.reflect.Modifier;

四、反射的常用方法
通过反射获取构造方法并使用

getConstructor 获取指定的公共构造方法
getConstructors()获取所有的公共构造方法

getDeclaredConstructor  获取指定的构造方法
getDeclaredConstructors获取所有的构造方法
创建对象
newInstance( ) 通过无参构造创建对象
newInstance(“zhangsan", 20);  通过带参构造创建对象
通过反射获取成员变量并使用
getFields,getDeclaredFields获取所有成员
getField,getDeclaredField获取单个成员
set(Object obj,Object value)将指定对象变量上此 Field 对象表示的字段设置为指定的新值。


通过反射获取成员方法并使用
getMethods获取所有方法(不包含private关键字修饰的方法)
getDeclaredMethods获取所有方法(包含private关键字修饰的方法)

getMethod获取单个方法(不包含private关键字修饰的方法)
getDeclaredMethod获取单个方法(包含private关键字修饰的方法)
method.setAccessible(true);  暴力访问,设置私有的方法可以被访问

反射的练习案例:

package UDP;//Person类public class Person {private String name;int age;public String address;public Person() {}Person(String name) {this.name = name;}private Person(String name, int age) {this.name = name;this.age = age;}public Person(String name, int age, String address) {this.name = name;this.age = age;this.address = address;}private void show(){System.out.println("hello");}public String run(String n,int a){return n+"-------"+a;}@Overridepublic String toString() {return "Person [name=" + name + ", age=" + age + ", address=" + address+ "]";}} 

//测试类1package Class;import java.lang.reflect.Constructor;public class ClassDemo1 {public static void main(String[] args) throws Exception {//获取字节码文件对象Class c=Class.forName("UDP.Person");//获取该字节码文件对象的所有构造方法Constructor[] conts=c.getDeclaredConstructors() ;for(Constructor cont:conts){System.out.println(cont);}}}

运行测试类1后的结果是:

由上图一可知,getDeclaredConstructors()方法获取到的是所有的构造方法,包括private关键字修饰的构造方法也能获取到。


//测试类2package Class;import java.lang.reflect.Constructor;public class ClassDemo3 {public static void main(String[] args) throws Exception {               //创建类的字节码对象Class c=Class.forName("UDP.Person");                //获取该字节码对象的两个参数的构造方法Constructor cons=c.getDeclaredConstructor(String.class,int.class);                //暴力访问私有构造方法(设置私有的构造方法可见)cons.setAccessible(true);                //通过两个参数的构造方法建立该字节码类的Object类型对象Object obj=cons.newInstance("张三",23);System.out.println(obj);}}


测试类2的运行结果是:


由图二可知,在不同的包下反射可以用Person类的私有构造方法创建Person对象。


//测试类3package Class;import java.lang.reflect.Constructor;import java.lang.reflect.Method;public class ClassDemo6 {public static void main(String[] args) throws Exception {//创建类的字节码对象Class c=Class.forName("UDP.Person");//获取该字节码对象的构造方法Constructor cons=c.getDeclaredConstructor();//通过无参构造方法建立该字节码类的Object类对象Object obj=cons.newInstance();Method m=c.getDeclaredMethod("show");//设置私有的方法可见m.setAccessible(true);m.invoke(obj);}}

测试类3运行的结果是:


由图三可知,可以通过字节码文件对象获取该类所有的方法并,并调用指定的方法

0 0