java反射机制
2016-05-26 09:42
716 查看
这是以前看了毕向东老师的视频所做的笔记,刚开始还是有点不理解,不过一两年再回头看看,其实自己做的笔记好像自己看的很有意思。(废话)
先看下面这幅图吧,看到什么
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
一个类有多个组成部分,例如:成年变量,方法,构造方法等。反射就是加载类,并解剖出类的各个组成部分。
反射技术一般用于框架中的获取,比如某个程序已经做好运行了,不可能再进行源代码的更改,此时想添加功能或修改,则我们自己写的代码怎么能放进去呢,这时就用到反射技术进行解剖类和方法,把我们的代码放进去。
编程时什么情况下才需要加载类,并解剖出类的各个组成部分呢?
比如:我们已经弄好了一个项目,那么项目里面的接口都是已经封装好的了 ,我们不可以直接调用里面的属性或方法,那么这时就用到反射了
java中有一个Class类用于代表某一个类的字节码。
Class类既然代表某个类的字节码,它当然就要提供加载某个类字节码的方法:
forName();forName方法用于加载某个类的字节码到内存中,并使用class对象进行封装。
另外两种得到class对象的方式
类名.class
对象.getClass()
Class对象提供如下常用方法:
public Constructor getConstructor(Class<?>...parameterTypes):获取字节码
public Method getMethod (Stringname.Class<?>...parameterTypes):获取方法
public Field getField (String name):获取字段)
Declared(可以拿类中的所有内容包括私有的)
public Constructor getDeclaredConstructor(Class...parameterTypes)
public Method getDeclaredMethod (Stringname.Class...parameterTypes)
public Field getDeclaredField (String name)
这些方法分别用于从类中解剖出构造函数、方法、成员变量(属性)。
解剖出的成员分别使用Constructor、Method、Field对象表示。
思考:假设你是一个框架的设计者,解剖出这些成员你会干什么?
反射类的构造函数
利用Constructor创建对象
Constructor类提供了如下方法,用于创建类的对象:
public Object newInstance(Object...initargs)
initargs用于指定构造函数接收的参数
练习:反射类无参、有参、私有的构造函数,创建类的对象。
多学一招:sun公司为简化开发人员创建对象,它在class对象中也提供了一个newInstance方法,用于创建类的对象。这样开发人员可以避免每次都需要去反射Constructor类创建对象。
不过需要注意的是:class.newInstance方法内部是反射类无参的构造函数创建对象,所以利用此种方式创建类对象时,类必须有一个无参的构造函数。
反射类的方法
利用Method执行方法
Method对象提供 了如下方法,用于执行它所代表的方法。
public Object invoke(Objectobj,Object...args)
练习:使用Method分别执行无参、有参、多个参(带数组和基本数据类型)、静态、私有的方法。
jdk1.4和jdk1.5的invoke方法的区别:
jdk1.5:public Object invoke(Object obj,Object...args)
jdk1.4:public Object invoke(Object obj,Object[]...args)
反射机制(获取Class中的构造函数)
反射机制(获取Class中的方法)
先看下面这幅图吧,看到什么
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
一个类有多个组成部分,例如:成年变量,方法,构造方法等。反射就是加载类,并解剖出类的各个组成部分。
反射技术一般用于框架中的获取,比如某个程序已经做好运行了,不可能再进行源代码的更改,此时想添加功能或修改,则我们自己写的代码怎么能放进去呢,这时就用到反射技术进行解剖类和方法,把我们的代码放进去。
编程时什么情况下才需要加载类,并解剖出类的各个组成部分呢?
比如:我们已经弄好了一个项目,那么项目里面的接口都是已经封装好的了 ,我们不可以直接调用里面的属性或方法,那么这时就用到反射了
java中有一个Class类用于代表某一个类的字节码。
Class类既然代表某个类的字节码,它当然就要提供加载某个类字节码的方法:
forName();forName方法用于加载某个类的字节码到内存中,并使用class对象进行封装。
另外两种得到class对象的方式
类名.class
对象.getClass()
//反射,加载类 获得类的字节码 public class Demo1 { public static void main(String[] args) throws ClassNotFoundException{ //1 Class clazz=Class.forName("cn.itcast.demo.Demo4"); //2 Class clazz1=new Demo4().getClass(); //3 Class clazz2=Demo4.class; } }
package cn.itcast.bean; /*java反射机制是在运行状态中,对于任意一个类(class文件),都能够 * 知道这个类的所有属性和方法。 * 这种动态获取的信息,就是java反射。 * 可以理解为对类的解剖。 * * 要想要对字节码文件进行解剖,必须要有字节码文件对象。 * 如何让获取字节码文件对象呢? * * * */ public class ReflectDemo { public static void main(String[] args) throws ClassNotFoundException { getClassObject_3(); } /*方式3: * 只要通过给定类的字符串名称就可以获取该类,更为扩展。 * 可以用Class类中的方法完成。 * 该方法就是forName * 这种方式只要有名称即可,更为方便,扩展性更强。 * */ public static void getClassObject_3() throws ClassNotFoundException { String className="cn.itcast.been.Person"; Class clazz=Class.forName(className); System.out.println(clazz); } /*方式2: * 2.任何数据类型都具备一个静态的属性.class来获取其对应的class对象。 *相对简单,但是还是需要明确用到类中的静态成员。 *还是不够扩展。 */ private static void getClassObject_2() { Class clazz=Person.class; Class clazz1=Person.class; System.out.println(clazz==clazz1); } /*获取字节码对象的方式: *1.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); } }
package cn.itcast.bean; public class 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 method(){ 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..."); } }
Class对象提供如下常用方法:
public Constructor getConstructor(Class<?>...parameterTypes):获取字节码
public Method getMethod (Stringname.Class<?>...parameterTypes):获取方法
public Field getField (String name):获取字段)
Declared(可以拿类中的所有内容包括私有的)
public Constructor getDeclaredConstructor(Class...parameterTypes)
public Method getDeclaredMethod (Stringname.Class...parameterTypes)
public Field getDeclaredField (String name)
这些方法分别用于从类中解剖出构造函数、方法、成员变量(属性)。
解剖出的成员分别使用Constructor、Method、Field对象表示。
思考:假设你是一个框架的设计者,解剖出这些成员你会干什么?
反射类的构造函数
利用Constructor创建对象
Constructor类提供了如下方法,用于创建类的对象:
public Object newInstance(Object...initargs)
initargs用于指定构造函数接收的参数
练习:反射类无参、有参、私有的构造函数,创建类的对象。
多学一招:sun公司为简化开发人员创建对象,它在class对象中也提供了一个newInstance方法,用于创建类的对象。这样开发人员可以避免每次都需要去反射Constructor类创建对象。
不过需要注意的是:class.newInstance方法内部是反射类无参的构造函数创建对象,所以利用此种方式创建类对象时,类必须有一个无参的构造函数。
反射类的方法
利用Method执行方法
Method对象提供 了如下方法,用于执行它所代表的方法。
public Object invoke(Objectobj,Object...args)
练习:使用Method分别执行无参、有参、多个参(带数组和基本数据类型)、静态、私有的方法。
jdk1.4和jdk1.5的invoke方法的区别:
jdk1.5:public Object invoke(Object obj,Object...args)
jdk1.4:public Object invoke(Object obj,Object[]...args)
反射机制(获取Class中的构造函数)
package cn.itcast.bean; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class ReflectDemo2 { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException { createNewObject_2(); } public static void createNewObject_2() throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException { // cn.itcast.bean.Person p=new cn.itcast.bean.Person(39,"小强"); /* * 当获取指定名称对应类中的所体现的对象时, * 而该对象初始化不使用空参数构造该怎么办呢? * 既然是通过指定的构造函数 进行对象的初始化, * 所以应该先获取到该构造函数。了、通过字节码文件对象即可完成。 * 该方法是:getConstructor(paramterTypes) * */ String name="cn.itcast.bean.Person"; Class clazz=Class.forName(name); Constructor constructor=clazz.getConstructor(String.class,int.class); //通过该构造器对象的newInstance方法进行对象的初始化。 Object obj=constructor.newInstance("小明",38); } public static void createNewObject()throws ClassNotFoundException, InstantiationException, IllegalAccessException{ //早期:new 的时候,先根据new的类的名称寻找该类的字节码文件,并加载进内存, //并创建该字节码文件对象,并接着创建该字节码文件的对应的Person对象。 //cn.itcast.bean.Person p=new cn.itcast.bean.Person(); //现在 String name="cn.itcast.bean.Person"; //寻找该名称类文件,并加载进内存,并产生Class对象。 Class clazz=Class.forName(name); //如何产生该类的对象呢? Object obj=clazz.newInstance(); } }反射机制(获取Class中的字段)
package cn.itcast.bean; import java.lang.reflect.Field; public class ReflectDemo3 { public static void main(String[] args) throws SecurityException, NoSuchFieldException, ClassNotFoundException, InstantiationException, IllegalAccessException { getFiledDemo(); } public static void getFiledDemo() throws SecurityException, NoSuchFieldException, ClassNotFoundException, InstantiationException, IllegalAccessException { Class clazz=Class.forName("cn.itcast.bean.Person"); //Field field=clazz.getField("age");//只能获取公共的 Field field=clazz.getDeclaredField("age");//只获取本类,但包含私有。 //对私有字段的访问取消权限检查。 field.setAccessible(true); Object obj=clazz.newInstance(); Object o=field.get(obj); System.out.println(o); } }
反射机制(获取Class中的方法)
package cn.itcast.bean; import java.lang.reflect.Constructor; import java.lang.reflect.Method; public class ReflectDemo4 { public static void main(String[] args) throws Exception { getMethodDemo_3(); } 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, "小强",89); } public static void getMethodDemo_2() throws Exception { Class clazz=Class.forName("cn.itcast.bean.Person"); Method method=clazz.getMethod("show",null);//获取show空参数方法 // Object obj=clazz.newInstance(); Constructor constructor=clazz.getConstructor(String.class,int.class); Object obj=constructor.newInstance("小明",37); method.invoke(obj, null); } public static void getMethodDemo() throws Exception { Class clazz=Class.forName("cn.itcase.bean.Person"); Method[]methods=clazz.getMethods();//获取的都是公有的方法 methods=clazz.getDeclaredMethods();//指获取本类中所有方法,包含私有的。 for(Method method:methods){ System.out.println(method); } } }
相关文章推荐
- ubunut 上搭建jdk 开发环境
- Spring中的mvc:interceptors标签配置拦截器
- java 读取文件
- JAVACV人脸识别代码下载 酷~~
- java类静态方法测试
- eclipse3.7 安装github插件错误解决
- java maven诡异的错误no class found
- Java读取Properties文件中在配置
- java学习笔记继承和多态5.24
- eclipse,myeclipse导入工程报:javax.servlet.jsp.JspException cannot be resolved to a type
- Java并发编程
- (java)集合辅助函数之Shuffle(打乱列表)
- java多线程中终止线程的方法的对别
- Java关键字及其作用总览
- Java中判断对象是否相等的equals()方法使用教程
- Java用类和对象,构造方法来实现超市管理系统
- Java开发常用的在线工具
- java入门教程-7.6Java isAlive()和join()的使用
- java入门教程-7.5Java创建多线程
- java入门教程-7.4Java创建线程(Runnable接口和Thread类)