Java 反射机制
根据李兴华的视频整理的
大致是先得到Class的类的对象,然后在用这个对象调用newInstance方法创建实例,就可以对实例进行操作了
Java反射的源头是Class这个类:
public final class Class<T>extends Objectimplements Serializable, GenericDeclaration, Type, AnnotatedElement
Class
类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class
对象。基本的 Java 类型(boolean
、byte
、char
、short
、int
、long
、float
和 double
)和关键字 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 Class<?> forName(String className) throws ClassNotFoundException
返回与带有给定字符串名的类或接口相关联的 Class
对象。
这个最常用啦,比如说java连接数据库加载驱动时:Class.forName("com.mysql.jdbc.Driver") ; 字符串为 包名.类名
2、类名.class
3、对象.getClass()
得到Class类的对象后就可以调用newInstance方法创建实例啦
public T newInstance() throws InstantiationException, IllegalAccessException
- 创建此 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 stub 25 try { 26 System.out.println(Class.forName("yxy.Person").newInstance()); 27 } catch (InstantiationException e) { 28 // TODO Auto-generated catch block 29 e.printStackTrace(); 30 } catch (IllegalAccessException e) { 31 // TODO Auto-generated catch block 32 e.printStackTrace(); 33 } catch (ClassNotFoundException e) { 34 // TODO Auto-generated catch block 35 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来整(有点儿像病句哇)
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 stub 29 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
呃,震惊了,私有属性和方法的也可以通过反射被看到:http://www.pengtaoblog.cn/article.asp?id=721
呃,原来这个人写的都有啦:http://www.cnblogs.com/octobershiner/archive/2012/03/18/2404751.html 这是个好文章
还有个好文章哇:候捷谈Java反射机制:http://www.cppblog.com/javenstudio/articles/24640.html
禁止反射:http://bbs.csdn.net/topics/390472034?page=1#post-394609835
反射的应用场景:http://bbs.itheima.com/thread-88932-1-1.html
第一讲 反射的应用场景
一、概述
反射技术:
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类中的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
简单一句话:反射技术可以对类进行解剖。
二、应用场景
一个已经可以使用的应用程序,因为程序已经做好可以运行使用,不能再进行代码的加入了。而当后期我们新的功能加入程序时,该怎么做呢?就如我们的电脑一样,后期我们可能会鼠标、键盘等,所以电脑给我们预留了usb接口,只要符合这个接口规则的设备,电脑就可以通过加载驱动等操作来使用。
那这个程序能用了,如何使用后期出现的功能类呢?
常用的作法,会提供一个配置文件,来供以后实现此程序的类来扩展功能。对外提供配置文件,让后期出现的子类直接将类名字配置到配置文件中即可。该应用程序直接读取配置文件中的内容。并查找和给定名称相同的类文件。进行如下操作:
1)加载这个类。
2)创建该类的对象。
3)调用该类中的内容。
应用程序使用的类不确定时,可以通过提供配置文件,让使用者将具体的子类存储到配置文件中。然后该程序通过反射技术,对指定的类进行内容的获取。
好处:反射技术大大提高了程序的扩展性。
|
更加详细的:http://blog.csdn.net/benjaminzhang666/article/details/9408611
crane:SSH框架中都用到了反射机制(读配置文件获得类名,然后进行反射操作)
《Effective Java》中文版第2版第53条中有说到反射机制的注意事项,
反射是在运行时执行的,丧失了编译时类型检查的好处,包括异常检查,如果程序反射的调用不存在的方法,在运行时会失败,除非采取了特别的预防措施。
详情参看那本书
posted on 2014-04-17 21:20 crane_practice 阅读(381) 评论(0) 编辑 收藏 举报