设计模式—Java反射机制

1.Java反射机制是什么?

       反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

       反射是Java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以运行时再装配,无需在组件之间进行源代码链接,但是反射使用不当会导致成本很高。

Java反射机制主要提供了以下功能:

  1. 在运行时判断任意一个对象的所属类
  2. 在运行时构造任意一个类的对象
  3. 在运行时判断任意一个类所具有的成员变量和方法
  4. 在运行时调用任意一个对象的方法
2.Java Reflection
       Reflection是实现Java反射机制的一个关键性质,反射机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public、static等)、 superclass(例如Object)、实现了的 interfaces (例如Serializable)、也包括其fields和methods的所有信息,并可于运行时改变fields内容或调用methods。 在JDK中主要由以下类开实现Java反射机制, 这些类(除了Class类)都位于java.lang.reflect包中。
  1. Class类:代表一个类,位于java.lang包下。
  2. Field类:代表类的成员变量(成员变量也称为类的属性)。
  3. Method类:代表类的方法。
  4. Constructor类:代表类的构造方法。
  5. Array类:提供了动态创建数组,以及访问数组的元素的静态方法。
Java反射机制通常借助Class、Field、Method和Constructor这四个类实现,其中最核心的就是Class类,它是反射的基础,在应用反射机制的过程中我们最关心的一般是一个类的构造器(Constructor类)、属性(Field类)和方法(Method类),下面我们主要介绍Class类和Class类中针对这三个元素的方法:
1)Class类
  • getName() -- 这个类型的全限定名
  • getSuperClass() -- 这个类型的直接超类的全限定名
  • isInterface() -- 这个类型是类类型还是接口类型
  • getTypeParamters() -- 这个类型的访问修饰符
  • getInterfaces() -- 任何直接超接口的全限定名的有序列表
  • getFields() -- 字段信息
  • getMethods() -- 方法信息
2)Field类
  • Field getField(String name) -- 获得命名的公共字段
  • Field[] getFields() -- 获得类的所有公共字段
  • Field getDeclaredField(String name) -- 获得类声明的命名的字段
  • Field[] getDeclaredFields() -- 获得类声明的所有字段
3)Method类
  • Method getMethod(String name, Class[] params) -- 使用特定的参数类型,获得命名的公共方法
  • Method[] getMethods() -- 获得类的所有公共方法
  • Method getDeclaredMethod(String name, Class[] params) -- 使用特写的参数类型,获得类声明的命名的方法
  • Method[] getDeclaredMethods() -- 获得类声明的所有方法
3.具体实现

1)通过一个对象获得完整的包名和类名

ReflectionTest test = new ReflectionTest();
System.out.println("ReflectionTest的包名为:" + test.getClass().getName());
//实例化Class类对象
Class<?> class1 = null;
Class<?> class2 = null;
Class<?> class3 = null;
class1 = Class.forName("reflection.ReflectionTest");
class2 = new ReflectionTest().getClass();
class3 = ReflectionTest.class;
System.out.println("class1的类名为:" + class1.getName());
System.out.println("class2的类名为:" + class2.getName());
System.out.println("class3的类名为:" + class3.getName());

2)获取一个对象的父类与实现的接口

Class<?> class4 = Class.forName("reflection.ReflectionTest");
//获取父类
Class<?> parentClass4 = class4.getSuperclass();
System.out.println("class4的父类为:" + parentClass4.getName());
//获取所实现的接口
Class<?> interfaceClass4[] = class4.getInterfaces();
System.out.println("class4实现的接口有:");
for(int i = 0; i < interfaceClass4.length; i++)
{
	System.out.println((i + 1) + ":" + interfaceClass4[i].getName());
}
3)通过反射机制实例化一个类的对象

package reflection;
//User类
public class User 
{
	private int age;
	private String name;
	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 reflect1()
	{
		System.out.println("Java 反射机制——调用User类中的reflect1()方法");
	}
	public void reflect2(int age, String name)
	{
		System.out.println("Java 反射机制——调用User类中的reflect2()方法");
		System.out.println("Name—> " + name + " Age—> " + age);
	}
}

Class<?> class5 = Class.forName("reflection.User");
//实例化默认构造方法,调用set进行赋值,调用get进行取值
User user = (User) class5.newInstance();
user.setAge(18);
user.setName("Tom");
System.out.println("Name = " + user.getName() + " Age = " + user.getAge());

4)获取某个类的全部属性

Class<?> class6 = Class.forName("reflection.ReflectionTest");
//取得本类的全部属性
Field[] field1 = class6.getDeclaredFields();
System.out.println("===============本类属性===============");
for(int i = 0; i < field1.length; i++)
{
	//权限修饰符
	int mod1 = field1[i].getModifiers();
	String modifier1 = Modifier.toString(mod1);
	//属性类型
	Class<?> type = field1[i].getType();
	System.out.println("属性类型为:" + type + " 权限修饰符为:" + modifier1 + "\n");
}
//取得实现的接口或者父类的属性
Field[] field2 = class6.getFields();
System.out.println("==========实现的接口或者父类的属性==========");
for(int i = 0; i < field2.length; i++)
{
	//权限修饰符
	int mod2 = field2[i].getModifiers();
	String modifier2 = Modifier.toString(mod2);
	//属性类型
	Class<?> type = field2[i].getType();
	System.out.println("属性类型为:" + type + " 权限修饰符为:" + modifier2 + "\n");
}
5)获取某个类的全部方法

Class<?> class7 = Class.forName("reflection.User");
//得到类中的全部方法
Method method[] = class7.getMethods();
System.out.println("============获取类的全部方法============");
for(int i = 0; i < method.length; i++)
{
	//得到方法的返回类型
	Class<?> returnType = method[i].getReturnType();
	//得到方法的全部参数
	Class<?> parameter[] = 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 < parameter.length; ++j) 
    {
        System.out.print(parameter[j].getName() + " " + "arg" + j);
        if (j < parameter.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();
}
6)通过反射机制调用某个类的方法

Class<?> class8 = Class.forName("reflection.User");
//调用User类中的reflect1()方法
Method methodReflect1 = class8.getMethod("reflect1");
methodReflect1.invoke(class8.newInstance());
//调用User类中的reflect2(int age, String name)方法
Method methodReflect2 = class8.getMethod("reflect2", int.class, String.class);
methodReflect2.invoke(class8.newInstance(), 36, "cat");
7)通过反射机制操作某个类中的属性

Class<?> class9 = Class.forName("reflection.User");
User user1 = (User) class9.newInstance();
//可以对private类型的属性直接赋值
Field fieldNmae = class9.getDeclaredField("name");
Field fieldAge = class9.getDeclaredField("age");
//获取给private类型的属性直接赋值的权限
fieldNmae.setAccessible(true);
fieldAge.setAccessible(true);
//对name和age进行赋值操作
fieldNmae.set(user1, "Tomcat");
fieldAge.set(user1, 24);
System.out.println("Name—> " + user1.getName() + " Age—> " + user1.getAge());
System.out.println(fieldNmae.get(user1));
System.out.println(fieldAge.get(user1));
8)在泛型为Integer的ArrayList中存放一个String类型的对象

ArrayList<Integer> list = new ArrayList<Integer>();
Method methodAdd = list.getClass().getMethod("add", Object.class);
methodAdd.invoke(list, "Java反射机制实例");
System.out.println(list.get(0));
9)通过反射取得并修改数组的信息

int[] array = {1, 2, 3, 4, 5, 6, 7, 8};
Class<?> class10 = array.getClass().getComponentType();
System.out.println("数组类型: " + class10.getName());
System.out.println("数组长度  " + Array.getLength(array));
System.out.println("数组的第一个元素: " + Array.get(array, 0));
Array.set(array, 0, 100);
System.out.println("修改之后数组第一个元素为: " + Array.get(array, 0));
10)通过反射机制修改数组的大小

int[] newArray = (int[]) Array.newInstance(class10, 10);
//将array中的数据复制到newArray中
System.arraycopy(array, 0, newArray, 0, array.length);
System.out.println("array数组的大小为(修改前):" + array.length);
for(int i = 0; i < array.length; i++)
{
	System.out.print(array[i] + " ");
}
System.out.println("");
System.out.println("array数组的大小为(修改后):" + newArray.length);
for(int i = 0; i < newArray.length; i++)
{
	System.out.print(newArray[i] + " ");
}
4.总结

       总的来说,java反射机制是一个很好用的东西,用它可以解决很多死的东西,因为反射机制的灵活行很大,有了他,我们就不要花太多的时间来写操做数据库的代码了,而是方法更多的时间在项目的逻辑功能上,这个可以很大的减少开发时间,而且代码的可读性好。先在的很多开源框架都是才用的反射机制,它只要配置文件,然后按规则来调用他的方法就可以了。


       以上Demo的源代码地址:点击打开链接

















  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值