博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java 反射机制
阅读量:5366 次
发布时间:2019-06-15

本文共 4436 字,大约阅读时间需要 14 分钟。

根据李兴华的视频整理的

大致是先得到Class的类的对象,然后在用这个对象调用newInstance方法创建实例,就可以对实例进行操作了

Java反射的源头是Class这个类:

public final class Class
extends implements , , ,

Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本的 Java 类型(booleanbytecharshortintlongfloatdouble)和关键字 void 也表示为 Class 对象。

Class 没有公共构造方法Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。

以下示例使用 Class 对象来显示对象的类名:

void printClassName(Object obj) {         System.out.println("The class of " + obj +                            " is " + obj.getClass().getName());     }

 实例化Class对象有3中方法:

1、Class.forName()

public static 
forName( className) throws

返回与带有给定字符串名的类或接口相关联的 Class 对象。

这个最常用啦,比如说java连接数据库加载驱动时:Class.forName("com.mysql.jdbc.Driver") ;  字符串为 包名.类名

2、类名.class

3、对象.getClass()

 

得到Class类的对象后就可以调用newInstance方法创建实例啦

public  newInstance()              throws ,
创建此
Class 对象所表示的类的一个新实例。如同用一个带有一个空参数列表的
new 表达式实例化该类。如果该类尚未初始化,则初始化这个类。 

注意:类中必须提供无参构造函数(如果不写构造函数,那么类本身就提供无参构造函数,如果写了构造函数,那么那个默认的就没有了),而且那个构造函数还得是可以访问的,如果是私有的话,那就不行啦

1 package yxy; 2  3 class Person{ 4     private String name; 5     public String getName() { 6         return name; 7     } 8  9     public void setName(String name) {10         this.name = name;11     }12     private Person(){13         this.setName("crane");14     }15     16     public String toString(){17         return "name= "+this.getName();18     }19 }20 21 public class Test {22     23     public static void main(String[] args) {24         // TODO Auto-generated method stub25         try {26             System.out.println(Class.forName("yxy.Person").newInstance());27         } catch (InstantiationException e) {28             // TODO Auto-generated catch block29             e.printStackTrace();30         } catch (IllegalAccessException e) {31             // TODO Auto-generated catch block32             e.printStackTrace();33         } catch (ClassNotFoundException e) {34             // TODO Auto-generated catch block35             e.printStackTrace();36         }37     }38 39 40 }
java.lang.IllegalAccessException: Class yxy.Test can not access a member of class yxy.Person with modifiers "private"    at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)    at java.lang.Class.newInstance(Unknown Source)    at yxy.Test.main(Test.java:26)

如果把12行改为public Person(){

则运行结果为:name= crane

如果是带参的可访问的构造函数也是不行的,

不过可以用getConstructors来整(有点儿像病句哇)

()返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。

 

1 package yxy; 2  3 import java.lang.reflect.Constructor; 4  5 class Person{ 6     private String name; 7     public String getName() { 8         return name; 9     }10 11     public void setName(String name) {12         this.name = name;13     }14     public Person(){15         this.setName("crane");16     }17     public Person(String name){18         this.setName(name);19     }20     public String toString(){21         return "name= "+this.getName();22     }23 }24 25 public class Test {26     27     public static void main(String[] args) throws Exception {28         // TODO Auto-generated method stub29         Class
c=null;30 c=Class.forName("yxy.Person");31 Constructor
[] cons=null;32 cons=c.getConstructors();33 Person person=null;34 //输出所有公有构造函数,私有的是不能得到的35 for(Constructor
con:cons){36 System.out.println(con);37 }38 person=(Person) cons[1].newInstance("crane");39 System.out.println(person);40 }41 }

运行结果:

public yxy.Person()public yxy.Person(java.lang.String)name= crane

 

 

 呃,震惊了,私有属性和方法的也可以通过反射被看到:

 

呃,原来这个人写的都有啦:  这是个好文章

还有个好文章哇:

 

禁止反射

 

反射的应用场景:

第一讲    反射的应用场景
一、概述
反射技术:
        Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类中的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
        简单一句话:反射技术可以对类进行解剖。
 
二、应用场景
        一个已经可以使用的应用程序,因为程序已经做好可以运行使用,不能再进行代码的加入了。而当后期我们新的功能加入程序时,该怎么做呢?就如我们的电脑一样,后期我们可能会鼠标、键盘等,所以电脑给我们预留了usb接口,只要符合这个接口规则的设备,电脑就可以通过加载驱动等操作来使用。
        那这个程序能用了,如何使用后期出现的功能类呢?
        常用的作法,会提供一个配置文件,来供以后实现此程序的类来扩展功能。对外提供配置文件,让后期出现的子类直接将类名字配置到配置文件中即可。该应用程序直接读取配置文件中的内容。并查找和给定名称相同的类文件。进行如下操作:
        1)加载这个类。
        2)创建该类的对象。
        3)调用该类中的内容。
       应用程序使用的类不确定时,可以通过提供配置文件,让使用者将具体的子类存储到配置文件中。然后该程序通过反射技术,对指定的类进行内容的获取。
        好处:反射技术大大提高了程序的扩展性。

更加详细的:

crane:SSH框架中都用到了反射机制(读配置文件获得类名,然后进行反射操作)

 

《Effective Java》中文版第2版第53条中有说到反射机制的注意事项,

反射是在运行时执行的,丧失了编译时类型检查的好处,包括异常检查,如果程序反射的调用不存在的方法,在运行时会失败,除非采取了特别的预防措施。

详情参看那本书

 

转载于:https://www.cnblogs.com/crane-practice/p/3671952.html

你可能感兴趣的文章
mysql asyn 示例
查看>>
数据库第1,2,3范式学习
查看>>
《Linux内核设计与实现》第四章学习笔记
查看>>
Docker 安装MySQL5.7(三)
查看>>
CSS: caption-side 属性
查看>>
CSS3中box-sizing的理解
查看>>
mysql导入source注意点
查看>>
linux下编译安装nginx
查看>>
DLL 导出函数
查看>>
windows超过最大连接数解决命令
查看>>
12个大调都是什么
查看>>
angular、jquery、vue 的区别与联系
查看>>
Intellij idea创建javaWeb以及Servlet简单实现
查看>>
代理网站
查看>>
Open multiple excel files in WebBrowser, only the last one gets activated
查看>>
FFmpeg进行视频帧提取&音频重采样-Process.waitFor()引发的阻塞超时
查看>>
最近邻与K近邻算法思想
查看>>
【VS开发】ATL辅助COM组件开发
查看>>
FlatBuffers In Android
查看>>
《演说之禅》I & II 读书笔记
查看>>