java加强之反射技术
来源:互联网 发布:元胞数组 编辑:程序博客网 时间:2024/06/03 10:12
——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
1.什么是反射?
答:反射是把Java类中的各种成分映射成一个个的java对象。例如,一个类有:成员变量,方法,构造方法,包等等信息,利用反射技术可以对一个类进行解剖,把各个组成部分映射成一个个对象。
2.反射用在哪里?
答:反射乃框架设计之灵魂。所以反射用在框架的书写,离开了框架反射没有太大的用处。
3.创建的对象的方式有几种,分别是什么。
答:2中,
1.通过new创建对象。
2.通过反射的方式创建对象。
4.要利用反射,必须先得到代表字节码的Class。Class类用于表示.class文件(字节码)。
如何得到某个class文件对应的class对象。
①类名.class,
②对象.getClass()
③Class.forName(“类名”)
注释:
基本类型的包装类.TYPE
总之,只要是在源程序中出现的类型,都有各自的Class实例对象,例如,int,void…
Class对象提供了如下常用方法:
public Constructor getConstructor(Class
package cn.itcast.base.reflect;import java.lang.reflect.Constructor;import org.junit.Test;public class Demo1 { //反射:public Person() @Test public void test1() throws Exception{ //得到字节码 Class clazz = Class.forName("cn.itcast.base.reflect.Person");//代表Person类在内存中的字节码对象// Class clazz = p.getClass();// Class clazz = Person.class; Constructor c = clazz.getConstructor(null);//得到构造方法干嘛?创建对象 c.newInstance(null); } @Test public void test11() throws Exception{ Class clazz = Class.forName("cn.itcast.base.reflect.Person"); Person p = (Person)clazz.newInstance();//调用默认的构造方法 System.out.println(p.name); } //反射:public Person(String name) @Test public void test2() throws Exception{ //得到字节码 Class clazz = Class.forName("cn.itcast.base.reflect.Person");//代表Person类在内存中的字节码对象 Constructor c = clazz.getConstructor(String.class); c.newInstance("朱巧玲"); } @Test//public Person(String name,int age) public void test3() throws Exception{ Class clazz = Class.forName("cn.itcast.base.reflect.Person"); Constructor c = clazz.getConstructor(String.class,int.class); Person p = (Person)c.newInstance("朱巧玲",20); System.out.println(p.name); } @Test//private Person(int age) public void test4() throws Exception{ Class clazz = Class.forName("cn.itcast.base.reflect.Person"); Constructor c = clazz.getDeclaredConstructor(int.class);//读取私有的构造方法的 c.setAccessible(true);//暴力反射 Person p = (Person)c.newInstance(20); System.out.println(p.name); } @Test//类中的所有构造方法 public void test5() throws Exception{ Class clazz = Class.forName("cn.itcast.base.reflect.Person"); Constructor[] cs = clazz.getDeclaredConstructors(); System.out.println(cs.length); }}
利用Method调用方法
Method提供了如下方法,用于执行它所代表的方法
public Object invoke(Object obj,Object…args)
package cn.itcast.base.reflect;import java.lang.reflect.Method;import java.util.Date;import org.junit.Test;//反射类中的方法public class Demo2 { //public void m1() @Test public void test1() throws Exception{ Class clazz = Person.class; Person p = (Person) clazz.newInstance(); Method m = clazz.getMethod("m1", null);//得到方法干嘛? m.invoke(p, null); } @Test//public void m2(String name) public void test2() throws Exception{ Class clazz = Person.class; Person p = (Person) clazz.newInstance(); Method m = clazz.getMethod("m2", String.class);//得到方法干嘛? m.invoke(p, "葛付以"); } @Test//public String m3(String name,int age) public void test3() throws Exception{ Class clazz = Person.class; Person p = (Person) clazz.newInstance(); Method m = clazz.getMethod("m3", String.class,int.class);//得到方法干嘛? String returnValue = (String)m.invoke(p, "葛付以",23); System.out.println(returnValue); } @Test//private void m4(Date d) public void test4() throws Exception{ Class clazz = Person.class; Person p = (Person) clazz.newInstance(); Method m = clazz.getDeclaredMethod("m4", Date.class);//得到方法干嘛? m.setAccessible(true); m.invoke(p,new Date()); } @Test//public static void m5() public void test5() throws Exception{ Class clazz = Person.class; Method m = clazz.getMethod("m5", null);//得到方法干嘛? m.invoke(null,null); } @Test//private static void m6(String[] strs) public void test6() throws Exception{ Class clazz = Person.class; Method m = clazz.getDeclaredMethod("m6",String[].class);//得到方法干嘛? m.setAccessible(true); m.invoke(null,(Object)new String[]{"a","b"}); } @Test public void test7() throws Exception{ Class clazz = Person.class; Method m = clazz.getMethod("main",String[].class);//得到方法干嘛? m.invoke(null,new Object[]{new String[]{"a","b"}}); }}
经典问题,反射main方法
jdk1.4和jdk1.5的invoke方法的区别
1.5:public Object invoke(Object obj,Object…args)1.4:public Object invoke(Object obj,Object[] args)
问题:
启动Java程序的main方法的参数是一个字符串数组,即public static void main(String[] args),通过反射方式来调用这个main方法时,如何为invoke方法传递参数呢?按jdk1.5的语法,整个数组是一个参数,而按jdk1.4的语法,数组中的每个元素对应一个参数,当把一个字符串数组作为参数传递给invoke方法时,javac会到底按照哪种语法进行处理呢?jdk1.5肯定要兼容jdk1.4的语法,会按jdk1.4的语法进行处理,即把数组打散成为若干个单独的参数。所以,在给main方法传递参数时,不能使用代码mainMethod.invoke(null,new String[]{“xxx”}),javac只把它当作jdk1.4的语法进行理解,而不把它当作jdk1.5的语法解释,因此会出现参数类型不对的问题。
解决办法:
mainMethod.invoke(null,new Object[]{new String[]{“xxx”}});
mainMethod.invoke(null,(Object)new String[]{“xxx”}); ,编译器会作特殊处理,编译时不把参数当作数组看待,也就不会数组打散成若干个参数了
反射字段:
package cn.itcast.base.reflect;import java.lang.reflect.Field;import java.util.Date;import org.junit.Test;//反射字段:Fieldpublic class Demo3 { //public String name="传智播客"; @Test public void test1() throws Exception{ Class clazz = Person.class; Person p = (Person)clazz.newInstance(); Field f = clazz.getField("name"); String s = (String)f.get(p); System.out.println(s); //更改name的值 f.set(p, "上海传智"); System.out.println(p.name); } @Test//private int age = 18; public void test2() throws Exception{ Class clazz = Person.class; Person p = (Person)clazz.newInstance(); Field f = clazz.getDeclaredField("age"); f.setAccessible(true); int age = (Integer)f.get(p); System.out.println(age); f.set(p, 28); age = (Integer)f.get(p); System.out.println(age); } @Test//public static Date time; public void test3() throws Exception{ Class clazz = Person.class; Field f = clazz.getField("time"); f.set(null, new Date()); System.out.println(Person.time); }}
补充:
1.关于类的状态图
2.
- java加强之反射技术
- 黑马程序员--JAVA基础加强之反射技术
- Java基础加强之反射
- Java基础加强之反射
- 黑马程序员_技术加强之反射
- Java技术加强之枚举
- Java基础加强之框架的概念及反射技术的开发框架的原理
- 黑马程序员-JAVA基础加强之反射
- JAVA基础加强之反射1
- JAVA基础加强之反射2
- 黑马程序员-Java基础加强之反射
- Java技术之反射
- Java 技术之反射
- Java 技术之反射
- 基础加强之反射
- 基础加强之反射
- java基础加强--反射
- Java基础加强---反射
- Android-SQLiteOpenHelper
- Android GridView属性集合
- spring中context:property-placeholder/元素
- qt显示图片汇总
- pomelo生命周期回调和组件添加
- java加强之反射技术
- Linux下zip压缩文件时怎样排除指定的文件
- 图像处理和图像识别中常用的OpenCV函数
- C++实现多线程安全的单例模式
- linux下安装飞信机器人教程
- GestureDetector封装手势检测上下滑动
- Android Framework内核之旅
- 版本控制-git(二)
- Redis 3.0 源码注释