反射
来源:互联网 发布:java list是类还是接口 编辑:程序博客网 时间:2024/05/23 16:17
参考这几篇博文
点击打开链接 点击打开链接2 点击打开链接3 点击打开链接4
反射机制,对于任何一个类(.class文件),能够知道这个类的所有属性和方法,对于任何一个对象,都能调用他的任一个方法和属性
也就说通过字节码文件去获取其中的类信息 ,所以必须先获得字节码对象
public class Person { int age; String name; public Person() {super();System.out.println("person run");}public Person(int age, String name) {super();this.age = age;this.name = name;System.out.println("person param run...."+this.name+" : "+this.age);}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public void show(){System.out.println(name+" .... "+age);}public 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......");}}
3种方法,第三种最为好用、常见,注意类名要带上包名
public class MyReflectDemo { public static void main(String[] args) throws ClassNotFoundException {getClassObject_1();getClassObject_2();getClassObject_3(); }/* * 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);}/* * 2.任何数据类型都具备一个静态属性 .class来获取class对象 * 相对简单,但是还是要用到类中的静态成员,不够扩展 */public static void getClassObject_2(){Class clazz = Person.class;Class clazz2 = Person.class;System.out.println(clazz == clazz2);}/* * 3.只要一个类的字符串名即可,最方便 * 用class类中的方法forName() * 这里必须带包名,不能直接用类名的字符串 */public static void getClassObject_3() throws ClassNotFoundException{String className = "bean.Person";Class clazz = Class.forName(className);System.out.println(clazz);}}
person runperson runtruetrueclass bean.Person
可以看到,前两个还是调用了构造函数
2.获取构造函数,newInstance()方法
public class MyReflectDemo2 { public static void main(String[] args) { /* * 这样写无需导包,早期的写法 * 要根据被new的对象找到做这个类的字节码文件加载到内存 * 再创建字节码文件的对象,以及该字节码文件对应的类的对象 */ /*bean.Person p = new bean.Person();*/ String name = "bean.Person"; Class clazz;try {//直接找到类文件加载到内存,并产生字节码文件的对象clazz = Class.forName(name);//通过newInstance方法产生类的对象Object obj = clazz.newInstance();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}catch (InstantiationException | IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} }}
person run
Person类里面必须有public的无参构造函数,没有的话会提示无法初始化,private会提示无法调用
当要调用的类对象没有无参构造时,先拿到一个构造器
public static void createNewObject2() { /* bean.Person p = new bean.Person(40,"小强");*/ /* * 当没有无参构造函数时,怎搞 * getConstructor(参数类型) */ String name = "bean.Person"; Class clazz;try {//找到文件加载进内存,产生字节码文件对象clazz = Class.forName(name);//获取指定构造函数对象Constructor cons = clazz.getConstructor(int.class,String.class); //通过构造器的newInstance()方法初始化Object obj = cons.newInstance(20,"小明");} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}catch (NoSuchMethodException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SecurityException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();} }
person param run....小明 : 20
3.获取字段
若是私有字段,需要设置下
public class MyReflectDemo3 { public static void main(String[] args) { getFieldDemo();}private static void getFieldDemo() {// TODO Auto-generated method stubClass clazz;Field field;try {clazz = Class.forName("bean.Person");/*//只能获取公有的field = clazz.getField("age");*///获取本类所有字段,包含私有field = clazz.getDeclaredField("age");//若私有,对私有字段的访问取消权限检查,暴力访问field.setAccessible(true);//找字段需要先找到对象Object obj = clazz.newInstance();field.set(obj, 89);//通过这个对象去找字段,返回的也是对象Object o = field.get(obj);System.out.println(o);} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}catch (NoSuchFieldException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SecurityException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
person run89
4.方法
所有方法
指定方法
带参方法
public class MyReflectDemo4 { public static void main(String[] args) { getMethodDemo(); getMethodDemo2(); getMethodDemo3(); } //获取所有公共方法 private static void getMethodDemo() { // TODO Auto-generated method stub try {Class clazz = Class.forName("bean.Person");Method[] methods = clazz.getMethods();methods = clazz.getDeclaredMethods();for (Method method:methods) {System.out.println(method);}} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} } //获取指定方法 private static void getMethodDemo2(){ Object obj; try {Class clazz = Class.forName("bean.Person");Method method = clazz.getMethod("show", null);//运行一个方法需要对象和参数Constructor cons = clazz.getConstructor(int.class,String.class);obj = cons.newInstance(26,"小明");method.invoke(obj, null);} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();}catch (ClassNotFoundException | NoSuchMethodException | SecurityException e) {// TODO Auto-generated catch blocke.printStackTrace();} } //获取带参方法 private static void getMethodDemo3(){ try {Class clazz = Class.forName("bean.Person");Method method = clazz.getMethod("paramMethod",String.class, int.class);Object obj = clazz.newInstance();method.invoke(obj,"小强",89);} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (NoSuchMethodException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SecurityException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();} }}
<pre name="code" class="plain">public void bean.Person.method()public void bean.Person.show()public void bean.Person.paramMethod(java.lang.String,int)public int bean.Person.getAge()public void bean.Person.setAge(int)public static void bean.Person.staticMethod()person param run....小明 : 26小明 .... 26person runparamMethod run.....小强 : 89
类的生命周期
在一个类编译完成之后,下一步就需要开始使用类,如果要使用一个类,肯定离不开JVM。在程序执行中JVM通过装载,链接,初始化这3个步骤完成。
类的装载是通过类加载器完成的,加载器将.class文件的二进制文件装入JVM的方法区,并且在堆区创建描述这个类的java.lang.Class对象。用来封装数据。
链接就是把二进制数据组装为可以运行的状态。
链接分为校验,准备,解析这3个阶段
校验一般用来确认此二进制文件是否适合当前的JVM(版本),
准备就是为静态成员分配内存空间,。并设置默认值
解析指的是转换常量池中的代码作为直接引用的过程,直到所有的符号引用都可以被运行程序使用(建立完整的对应关系)
完成之后,类型也就完成了初始化,初始化之后类的对象就可以正常使用了,直到一个对象不再使用之后,将被垃圾回收。释放空间。
当没有任何引用指向Class对象时就会被卸载,结束类的生命周期
反射一般是给设计框架的人用的,因为他需要先搭架子,但具体要操作的对象是什么还不知道,所以要用反射来做。
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 程序编译后运行时的内存分配
- android图片压缩质量参数Bitmap.Config RGB_565等的含义
- Convert UOM values
- OC 中new与alloc/init的区别
- android 推送消息
- 反射
- UOM Conversion Relationship Not Found
- 黑马程序员_C语言基础_数组之冒泡排序、快速选择排序、折半查找
- ofbiz送货地址
- MVP模式在Android开发中的应用
- 每日总结
- LeetCode || Single Number
- Android开发之SQLite的使用方法
- CentOS6/CentOS7下开启端口