Java的反射机制
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
JAVA反射(反射)机制:"程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言"。从这个观点看,Perl,Python,Ruby是动态语言,C++,java,C#不是动态语言。但是Java有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以与运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括method定义),并生成其对象实体、或对其fields设置,或唤起其methods。
Java反射机制主要提供了一下功能:
-
在运行时判断任意一个对象所属的类;
-
在运行时构造任意一个类的对象;
-
在运行时判断任意一个类所具有的成员变量和方法;
-
在运行时调用任意一个对象的方法;
-
生成动态代理;
附:反射的基本例子
1.通过反射实例化一个对象
package reflect.demo1;
//通过一个对象获得完整的包名和类名
public class TestReflect1 {
public static void main(String[] args) throws Exception {
Class<?> class1=null;
Class<?> class2=null;
Class<?> class3=null;
class1=Class.forName("reflect.demo1.TestReflect1");
class2=new TestReflect2().getClass();
class3=TestReflect1.class;
System.out.println(class1.getName());
System.out.println(class2.getName());
System.out.println(class3.getName());
}
}
2.通过一个对象获得完整的包名和类名
package reflect.demo1;
//通过一个对象获得完整的包名和类名
public class TestReflect2 {
public static void main(String[] args) {
TestReflect2 testReflect=new TestReflect2();
System.out.println(testReflect.getClass().getName());
}
}
3.获得一个对象的父类与实现的接口
package reflect.demo1;
import java.io.Serializable;
//获得一个对象的父类与实现的接口
public class TestReflect3 implements Serializable {
private static final long serialVersionUID=-2862585049955236662L;
public static void main(String[] args) throws Exception {
Class<?> clazz=Class.forName("proxy.demo1.TestReflect");
Class<?> parentClass=clazz.getSuperclass();
System.out.println(parentClass.getName());
Class<?> intes[]=clazz.getInterfaces();
for(int i=0;i<intes.length;i++){
System.out.println(intes[i].getName());
}
}
}
4.通过反射机制实例化一个类的对象
package reflect.demo1;
import java.lang.reflect.Constructor;
//通过反射机制实例化一个类的对象
//获取某个类中的全部构造函数
public class TestReflect4 {
public static void main(String[] args) throws Exception {
Class<?> class1=null;
class1=Class.forName("reflect.demo1.User");
//第一种方法,实例化默认构造方法,调用set赋值
User user=(User)class1.newInstance();
user.setAge(20);
user.setName("Rollen");
System.out.println(user.getAge());
System.out.println(user.getName());
//第二种方法 取得全部的构造函数 使用构造函数赋值
Constructor<?> cons[]=class1.getConstructors();
//查看每个构造方法需要的参数
for(int i=0;i<cons.length;i++){
Class<?> clazzs[]=cons[i].getParameterTypes();
System.out.print("cons["+i+"] (");
for(int j=0;j<clazzs.length;j++){
if(j==clazzs.length){
System.out.print(clazzs[j].getName());
}else{
System.out.print(clazzs[j].getName()+",");
}
}
System.out.println(")");
}
user=(User) cons[1].newInstance(20,"Rollen");
System.out.println(user);
}
}
5.取得本类中的全部属性
package reflect.demo1;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class TestReflect5 implements Serializable{
private static final long serialVersionUID=-2862585049955236662L;
public static void main(String[] args) throws Exception{
Class<?> clazz=Class.forName("reflect.demo1.TestReflect5");
System.out.println("========本类属性========");
//取得本类中的全部属性
Field[] field=clazz.getDeclaredFields();
for(int i=0;i<field.length;i++){
//权限修饰符
int mo=field[i].getModifiers();
String priv=Modifier.toString(mo);
//属性类型
Class<?> type=field[i].getType();
System.out.println(priv);
System.out.println(field[i].getName());
}
System.out.println("========实现的接口或者父类的属性======");
//取得实现的接口或者父类的属性
Field[] filed1=clazz.getFields();
for(int j=0;j<filed1.length;j++){
//权限修饰符
int mo=filed1[j].getModifiers();
String priv=Modifier.toString(mo);
//属性类型
Class<?> type=filed1[j].getType();
System.out.println(priv);
System.out.println(type.getName());
}
}
}
6.获取某个类的全部方法去
package reflect.demo1;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
//获取某个类的全部方法去
public class TestReflect6 {
private static final long serialVersionUID = -2862585049955236662L;
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("reflect.demo1.TestReflect6");
Method method[] = clazz.getMethods();
for (int i = 0; i < method.length; ++i) {
Class<?> returnType = method[i].getReturnType();
Class<?> para[] = method[i].getParameterTypes();
int temp = method[i].getModifiers();
System.out.print(Modifier.toString(temp) + " ");
System.out.print(returnType.getName() + " ");
System.out.print(method[i].getName() + " ");
System.out.print("(");
for (int j = 0; j < para.length; ++j) {
System.out.print(para[j].getName() + " " + "arg" + j);
if (j < para.length - 1) {
System.out.print(",");
}
}
Class<?> exce[] = method[i].getExceptionTypes();
if (exce.length > 0) {
System.out.print(") throws ");
for (int k = 0; k < exce.length; ++k) {
System.out.print(exce[k].getName() + " ");
if (k < exce.length - 1) {
System.out.print(",");
}
}
} else {
System.out.print(")");
}
System.out.println();
}
}
}
7.通过反射机制调用某个类的方法
package reflect.demo1;
import java.lang.reflect.Method;
//通过反射机制调用某个类的方法
public class TestReflect7 {
public static void main(String[] args) throws Exception{
Class<?> clazz=Class.forName("reflect.demo1.TestReflect7");
//调用TestReflect类中的reflect1方法
Method method=clazz.getMethod("reflect1");
method.invoke(clazz.newInstance());
System.out.println("");
method=clazz.getMethod("reflect2", int.class,String.class);
method.invoke(clazz.newInstance(),20,"张三");
}
public void reflect1(){
System.out.println("java reflect invoke method1");
}
public void reflect2(int age,String name){
System.out.println("java reflect invoke method2");
System.out.println("age:"+age+" "+"name:"+name);
}
}
8.通过反射机制操作某个类的属性
package reflect.demo1;
import java.lang.reflect.Field;
//通过反射机制操作某个类的属性
public class TestReflect8 {
private String proprety="kexinxin";
public static void main(String[] args)throws Exception{
Class<?> clazz=Class.forName("reflect.demo1.TestReflect8");
Object obj=clazz.newInstance();
//可以直接对private的属性赋值
Field field=clazz.getDeclaredField("proprety");
System.out.println(field.get(obj));
field.setAccessible(true);
field.set(obj, "java reflect");
System.out.println(field.get(obj));
TestReflect8 testReflect=new TestReflect8();
System.out.println(testReflect.getClass().getClassLoader().getClass().getName());
}
}
9.反射机制的应用实例
package reflect.demo1;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
//反射机制的应用实例,在泛型为Integer的ArrayList中存放一个String类型的对象
public class TestReflect9 {
public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
ArrayList<Integer> list=new ArrayList<Integer>();
Method method=list.getClass().getMethod("add", Object.class);
method.invoke(list, "Java反射机制实例");
System.out.println(list.get(0));
}
}
10.通过反射取得并修改数组的信息
package reflect.demo1;
import java.lang.reflect.Array;
//通过反射取得并修改数组的信息
public class TestReflect10 {
public static void main(String[] args) throws Exception {
int[] temp = { 1, 2, 3, 4, 5 };
Class<?> demo = temp.getClass().getComponentType();
System.out.println("数组类型: " + demo.getName());
System.out.println("数组长度 " + Array.getLength(temp));
System.out.println("数组的第一个元素: " + Array.get(temp, 0));
Array.set(temp, 0, 100);
System.out.println("修改之后数组第一个元素为: " + Array.get(temp, 0));
}
}
11.通过反射机制修改数组的大小
package reflect.demo1;
import java.lang.reflect.Array;
//通过反射机制修改数组的大小
public class TestReflect11 {
public static void main(String[] args) throws Exception {
int[] temp = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int[] newTemp = (int[]) arrayInc(temp, 15);
print(newTemp);
String[] atr = { "a", "b", "c" };
String[] str1 = (String[]) arrayInc(atr, 8);
print(str1);
}
// 修改数组大小
public static Object arrayInc(Object obj, int len) {
Class<?> arr = obj.getClass().getComponentType();
Object newArr = Array.newInstance(arr, len);
int co = Array.getLength(obj);
System.arraycopy(obj, 0, newArr, 0, co);
return newArr;
}
// 打印
public static void print(Object obj) {
Class<?> c = obj.getClass();
if (!c.isArray()) {
return;
}
System.out.println("数组长度为: " + Array.getLength(obj));
for (int i = 0; i < Array.getLength(obj); i++) {
System.out.print(Array.get(obj, i) + " ");
}
System.out.println();
}
}