想起来之前之前面试过的一个程序员,我问了这样的一个问题,“你了解什么是反射机制吗?”
他说:“反射?不就是Class.forname()吗,知道。”然后就没有然后了……
所以今天就简单地来聊聊Java当中的反射机制到底是怎么回事。
什么是反射机制?Java反射技术应用广泛,它能配置:类的全限定名、方法、完成对象的初始化,甚至是反射某些方法。
反射机制可以理解成一种动态创建对象的过程,和new一样,都能够用来创建对象。只不过反射机制除了能创建对象以外,还能够了解对象当中的内部结构,包括属性、方法、构造方法等。
为什么要要反射?使用反射的目的是增加程序的灵活性,使程序在必要的时候使用非new的方式来创建对象。目前在框架中使用反射机制是用得最彻底的,例如Spring框架、Mybatis框架等等。
反射到底怎么用?1、无参构造函数反射对象
当类中的构造函数没有参数时,具体代码如下:
package com.fs.test;
public class Student {
public Student() {} //无参构造函数
public void sayHello() {
System.out.println("hello");
}
}
package com.fs.test;
public class MyMain {
public static void main(String[] args)throws Exception{
//获取Student字节码文件
Class clazz = Class.forName("com.fs.test.Student");
//生成Student对象
Student stu = (Student)clazz.newInstance();
stu.sayHello();//调用方法
}
}
输出结果为:hello
2、有参数的构造函数反射对象
当类中构造函数带有参数时,具体代码如下:
package com.fs.test;
public class Student {
String name;
public Student(String name) {
this.name = name;
}
public void sayHello() {
System.out.println("hello" name);
}
}
package com.fs.test;
import java.lang.reflect.Constructor;
public class MyMain {
public static void main(String[] args)throws Exception{
//获取Student字节码文件
Class clazz = Class.forName("com.fs.test.Student");
//获取构造函数对象,并指明构造函数中参数的数据类型
Constructor constructor = clazz.getConstructor(String.class);
//生成Student对象,并指定构造函数的实际参数
Student stu = (Student)constructor.newInstance("小明");
//调用方法
stu.sayHello();
}
}
输出结果为:hello小明
3、私有的构造函数反射对象
如果类中的构造函数由private修饰,以上方法就不能用了,要先将其设置成可访问性的再进行反射。(这里就能看出来反射其实是有一定安全隐患的,它可以无视private),具体代码如下:
package com.fs.test;
public class Student {
private Student() {}
public void sayHello() {
System.out.println("hello");
}
}
package com.fs.test;
import java.lang.reflect.Constructor;
public class MyMain {
public static void main(String[] args)throws Exception{
//获取Student字节码文件
Class clazz = Class.forName("com.fs.test.Student");
//获取构造函数
Constructor constructor = clazz.getDeclaredConstructor();
//设置该构造函数对象为可读
constructor.setAccessible(true);
//生成对象
Student stu = (Student)constructor.newInstance();
//调用方法
stu.sayHello();
}
}
输出结果为:hello
4、反射类中方法
如果要反射类中的方法,必须要先有对象。具体代码如下:
package com.fs.test;
public class Student {
public Student() {}
public void sayHello(String name) {
System.out.println("hello" name);
}
}
package com.fs.test;
import java.lang.reflect.Method;
public class MyMain {
public static void main(String[] args)throws Exception{
//获取Student字节码文件
Class clazz = Class.forName("com.fs.test.Student");
//生成对象
Student stu = (Student)clazz.newInstance();
//获得方法对象
Method method = stu.getClass().getMethod("sayHello",String.class);
//反射方法
method.invoke(stu,"张三");
}
}
getMethod()函数第一个参数为要反射的方法的名称,第二个参数为该方法中参数的数据类型。
invoke()函数第一个参数为具体要反射哪个对象的方法,第二个参数为方法中的实际参数。
method.invoke(stu,"张三")相当于stu.sayHello("张三")
输出结果为:hello张三
以上是我对Java反射的一些理解,关注我,每天分享编程小知识
,