java反射(Reflection)介绍
Java 反射机制可以让我们在程序编译期(Compile Time)之外的运行期(Runtime)可以拿到一个对象的所有信息,比如检查类,接口,变量以及方法的信息。反射还可以让我们在运行期实例化对象,调用方法,通过调用 get/set 方法获取变量的值。
反射也是java被视为动态语言的一个关键特性。
反射实现功能概述
1. 只要给定类的全名就能通过反射来获取类的所有信息,比如构造器,父类,包信息,变量,注解等。
2. 反射可以在程序运行时候获取任意对象所属的类对象。
3. 在运行时候可以获取类中所有属性对象,并对其操作(包括私有属性)。
4. 在运行时候可以获取类中,父类中所有方法并调用。
5. 目前java主流框架Struct2,Spring,SpringMvc等框架等核心都有利用反射机制来实现的。
Class对象的机制与实现
在面向对象世界中,万事万物皆对象。java有两种对象,分别是实例对象和Class对象。每个类的运行时的类型信息就是用Class对象表示的,但是java中也有几个不是对象。
1. 普通数据类型不是对象,int a = 5就是不是对象,但是它有包装类。
2. java里静态的东西,不是对象,但是属于某个类的。
除了int
等基本类型外,Java的其他类型全部都是class
(包括interface
),比如String
,Object
,Runnable
,Exception
等。
Class概述
1. Class其实就是类的类型。
2. 字符串类型就是String,整形类型就是Integer,String和Integer类型就是Class。
Class对象常用方法介绍
1. getName:获取类中完整名称。
2. getDeclaredFields():获取类中所有属性,包括私有属性。
3. getFields():获取类中所有属性,不包括私有属性。
4. getDeclaredMethods():获取类中所有方法。
5. getConstructors():获取类构造方法。
6. newInstance():实例化类对象(只用用于无参)。
获取Class对象的三种方式
代码如下
Book.java
package xiana; public class Book { private int id; private String name; private String type;
public int price;
public int getId() {
return id;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getType() { return type; } public void setType(String type) { this.type = type; } }
测试类BookTest.java,该文件中包含三种获取Class对象的方法。
package xiana; public class BookTest { public static void main(String[] args) { //申明三种类 Class class1 = null; Class class2 = null; Class class3 = null; //第一种:通过Class的静态forName方法来获取类对象Class实例 try { class1 = Class.forName("xiana.Book"); //forName方法括号中跟上类的全路径 } catch(Exception e) { e.printStackTrace(); } System.out.println(class1); //结果:class xiana.Book //第二种:通过类的实例化类对象来获取类对象 Book bo = new Book(); Object ob = bo; System.out.println(ob.getClass()); //结果:class xiana.Book //第三种 class3 = Book.class; System.out.println(class3); //结果:class xiana.Book //通过类对象来实例化一个对象 try { Book bobject = (Book)class3.newInstance(); //使用上面第三个class3类对象 这里需要用try catch包裹起来 System.out.println(bobject); //结果:xiana.Book@7852e922 @7852e922这个是内存地址 } catch(InstantiationException e) { e.printStackTrace(); } catch(IllegalAccessException e) { e.printStackTrace(); } } }
Field对象的机制和实现
Field对象概述:
1. Java.lang.reflect.Field类,是用于表示类中,接口中属性对象的类。
2. 可以操作类中私有,以及公有等全部属性和属性的信息。
Field对象常用方法:
1. getName:获取属性名称。
2. getType:获取属性类型。
3. get(Object obj):获取obj对象中这个属性的值。
4. set(Object obj, Object value):像obj对象这个属性赋值。
5. setAccessible(true):启动/禁用访问控制权限。
package xiana; import java.lang.reflect.Field; public class BookTest { //该方法用于使用传递过来的Class对象获取类中的属性 public void show(Class cl) { //存放属性数组 Field[] fi = cl.getDeclaredFields(); System.out.println("使用getDeclaredFields"); for (Field ff : fi ) { System.out.println("Name="+ff.getName()); //打印所有属性的名称 System.out.println("Type="+ff.getType());//打印所有属性的类型 } System.out.println("使用getFields"); Field[] fi1 = cl.getFields(); for (Field ff : fi1 ) { System.out.println("Name="+ff.getName()); System.out.println("Type="+ff.getType()); } } public static void main(String[] args) { Book bo = new Book(); //设置book对象一些属性的值 bo.setId(1); bo.setName("三体"); bo.setType("科幻"); BookTest bt = new BookTest(); bt.show(Book.class); } }
结果
可以明显看出getDeclaredFields可以返回所有属性,包括私有属性,而getFields方法只能返回公共属性。
java动态加载类