黑马程序员-----反射
2015-11-09 12:47
274 查看
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
反射
Java反射机制是在运行状态中,对于任意一个类(class文件),都能够知道这个类中的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
[align=left] 动态获取类中信息,就是java反射。可以理解为对类的解剖。 如果想要对指定名称的字节码文件进行加载并获取其中的内容并调用,这时就使用到了反射技术。[/align]
[/align]
获取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是一个类名
这种方式仅知道类名就可以获取到该类字节码对象的方式,更有利于扩展。
练习:获取字节码对象的三种方式:
1)得到这个类的所有构造方法:如得到上面示例中Person类的所有构造方法
Constructor[] cons = Class.forName(“cn.itheima.Person”).getConstructors();
2)获取某一个构造方法:
Constructor con=Person.class.getConstructor(String.class,int.class);
2、方法
Field getField(String s);//只能获取公有和父类中公有
Field getDeclaredField(String s);//获取该类中任意成员变量,包括私有
setAccessible(ture); //如果是私有字段,要先将该私有字段进行取消权限检查的能力。也称暴力访问。
set(Object obj, Object value);//将指定对象变量上此Field对象表示的字段设置为指定的新值。
Object get(Object obj);//返回指定对象上Field表示的字段的值。
示例:
Method[] getMethods();//只获取公共和父类中的方法。
Method[] getDeclaredMethods();//获取本类中包含私有。
Method getMethod("方法名",参数.class(如果是空参可以写null));
Object invoke(Object obj ,参数);//调用方法
如果方法是静态,invoke方法中的对象参数可以为null。
反射
一、概述
反射技术:Java反射机制是在运行状态中,对于任意一个类(class文件),都能够知道这个类中的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
[align=left] 动态获取类中信息,就是java反射。可以理解为对类的解剖。 如果想要对指定名称的字节码文件进行加载并获取其中的内容并调用,这时就使用到了反射技术。[/align]
二、反射的基础Clsss类
[align=left] 用于描述字节码的类就是Class类,创建对象,可以提取字节码文件中的内容,如字段、构造函数、一般函数。该类就可以获取字节码文件中的所有内容,那么反射就是依靠该类完成的。想要对一个类文件进行解剖,只要获取到该类的字节码文件对象即可。[/align]
获取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); } }
相关文章推荐
- 有人说中文编辑是解决中国程序员编程效率的秘密武器,请问他是一个银弹吗?
- 经典面试题-螺旋打印OC版
- 有了这个列表,程序员不愁没练手的小项目了
- P147、面试题26:复杂链表的复制
- P143、面试题25:二叉树中和为某一值的路径
- 国造为什么总是质量差的代名词----献给良心做事的程序员们,以及其他行业默默认真地工作者们
- 月薪3万的程序员都避开了哪些坑
- iOS面试题
- java 多线程与并发基础面试
- 程序员眼中的英语单词
- 写给浮躁的程序员
- 程序员跳槽攻略
- 程序员眼中的单词
- 程序员,这12个问题让经理比你痛苦多了
- 黑马程序员_OC学习日记1
- Java:Java程序员进阶
- 这些 iOS 面试基础题目,你都深入了解吗?
- 三季度全国招聘放缓,超4成职场人想跳槽
- 程序员,这12个问题让经理比你痛苦多了
- ——黑马程序员——OC中block的基本概念