一、什么是反射
java程序在运行期间能够动态加载、解析、使用一些在编译阶段并不确定的数据类型
二、反射的功能
2、1、加载运行时才能确定的数据类型
2、2、解析类的结构,获取内部信息
2、3、操作该类型或其实例:访问属性、调用方法、创建新对象
package com.study.test;
import static java.lang.System.out;
class aaa {
void test() {
out.println("您好!");
}
}
public class ClassLoaderJZ {
public static void main(String[] args) throws Exception {
// 反射的概览
// 传统的实现test方法的调用通过如下方式
aaa a1 = new aaa();
a1.test();
// 通过反射来实现test方法的调用
aaa.class.newInstance().test();// 获取类模板调用方法实例化对象,最后调用test方法,更加简洁
// 返回默认的无参构造函数 返回类型为数组
out.println(aaa.class.getDeclaredConstructors()[0]);
out.println(aaa.class.getSuperclass());// 返回aaa的父类Object
// 输出为空可知Object已经是最高的父类了,不能再回溯了
out.println(aaa.class.getSuperclass().getSuperclass());
}
}
三、获取Class对象的方法
3、1、Class的静态函数forName()获取
3、2、调用从Object继承下来的getClass()函数
3、3、通过.class表达式获取
package com.study.test;
import static java.lang.System.out;
class aaa {
void test() {
out.println("您好!");
}
}
public class ClassLoaderJZ {
public static void main(String[] args) throws Exception {
// 获取Class对象的途径
// 针对引用数据类型
//1、Class的静态函数forName()获取
Class<?> c1 = Class.forName("com.study.test.aaa");
out.println(c1);
// 2、调用从Object继承下来的getClass()函数
aaa a1 = new aaa();
Class<?> c2 = a1.getClass();
out.println(c2);
// 3、通过.class表达式获取
out.println(aaa.class);
Class<aaa> c3 = aaa.class;
out.println(c3);
// 针对基本数据类型及void
// 通过TYPE属性得到包装类的基本类型
int i = 1;// 栈区存储 基本类型
Integer j = new Integer(1);// 堆区存储 包装类 等于Integer j=1;
Class<Integer> c4 = Integer.TYPE;// 输出int 返回包装类的基本类型
out.println(c4);
// 使用.class 表达式
Class c5 = int.class;
Class c6 = double.class;
Class c7 = void.class;
out.println(c5);
out.println(c6);
out.println(c7);
}
}
四、反射操作构造函数
4、1 调用无参、有一个参数、有多个参数的构造函数实例化对象
package com.study.test;
import static java.lang.System.out;
import java.lang.reflect.Constructor;
class aaa {
aaa() {
out.println("aaa()");
}
aaa(int i) {
out.println("aaa(int i)");
}
aaa(int i, String j) {
out.println("aaa(int i,String j)");
}
void test() {
out.println("void test()");
}
}
public class ClassLoaderJZ {
public static void main(String[] args) throws Exception {
// 通过反射我们获得了构造函数的规则 我们获得的是构造函数的数组
out.println(aaa.class.getDeclaredConstructors().length);
// out.println(aaa.class.getDeclaredConstructors()[0].newInstance());
// out.println(aaa.class.getDeclaredConstructors()[1].newInstance(1));
// 遍历输出构造函数 默认按参数个数的多少由大到小一次输出
for (Constructor<?> c1 : (aaa.class.getDeclaredConstructors())) {
out.println(c1);
}
// 怎样通过反射实例化调用函数?
// aaa.class.newInstance().test(new int[]{4,5,6});
// 错的aaa.class.getDeclaredConstructors()[0].newInstance(1);
// //传统方案调用test
// aaa a1=new aaa();
// a1.test(new int[]{1,2,3});
// 调用无参的构造函数动态生成实例
// aaa.class.newInstance().test();
aaa.class.getDeclaredConstructors()[2].newInstance();
// 调用带一个参数构造函数生成实例
aaa.class.getDeclaredConstructors()[1].newInstance(1);
// 调用带两个参数构造函数生成实例
aaa.class.getDeclaredConstructors()[0].newInstance(1, "abc");
}
}
输出结果:
3
com.study.test.aaa(int,java.lang.String)
com.study.test.aaa(int)
com.study.test.aaa()
aaa()
aaa(int i)
aaa(int i,String j)
4、2 获取构造函数的修饰符、名字、以及参数
package com.study.test;
import static java.lang.System.out;
import java.lang.reflect.Constructor;
class aaa {
aaa() {
out.println("aaa()");
}
aaa(int i) {
out.println("aaa(int i)");
}
aaa(int i, String j) {
out.println("aaa(int i,String j)");
}
void test() {
out.println("void test()");
}
}
public class ClassLoaderJZ {
public static void main(String[] args) throws Exception {
// 通过反射我们获得了构造函数的规则 我们获得的是构造函数的数组
out.println(aaa.class.getDeclaredConstructors().length);
// out.println(aaa.class.getDeclaredConstructors()[0].newInstance());
// out.println(aaa.class.getDeclaredConstructors()[1].newInstance(1));
// 遍历输出构造函数 默认按参数个数的多少由大到小一次输出
// getConstructors()函数获取public的构造函数;getDeclaredConstructors()获取所有的构造函数
for (Constructor<?> c1 : (aaa.class.getDeclaredConstructors())) {
// 获取构造函数的修饰符、名字、参数类型
out.println("获取构造函数的修饰符、名字、参数类型");
out.println(c1.getModifiers());
out.println(c1.getName());
for (Class c2 : c1.getParameterTypes()) {
out.println(c2);
}
}
}
}
输出结果:
3
获取构造函数的修饰符、名字、参数类型
0
com.study.test.aaa
int
class java.lang.String
获取构造函数的修饰符、名字、参数类型
0
com.study.test.aaa
int
获取构造函数的修饰符、名字、参数类型
0
com.study.test.aaa
五、反射获取接口.
package com.study.test;
import static java.lang.System.out;
interface I1 {
}
interface I2 {
}
class aaa implements I1, I2 {
public aaa() {
out.println("aaa()");
}
private aaa(int i) {
out.println("aaa(int i)");
}
protected aaa(int i, String j) {
out.println("aaa(int i,String j)");
}
void test() {
out.println("void test()");
}
}
public class ClassLoaderJZ {
public static void main(String[] args) throws Exception {
// 获取接口
out.println("获取接口");
for (Class<?> c2 : aaa.class.getInterfaces()) {
out.println(c2);
}
}
}
输出结果:
获取接口
interface com.study.test.I1
interface com.study.test.I2
六、反射获取方法的返回类型,修饰符,参数类型等等
package com.study.test;
import static java.lang.System.out;
import java.lang.reflect.Method;
interface I1 {
}
interface I2 {
}
class aaa implements I1, I2 {
public aaa() {
out.println("aaa()");
}
private aaa(int i) {
out.println("aaa(int i)");
}
protected aaa(int i, String j) {
out.println("aaa(int i,String j)");
}
void test() throws Exception {
out.println("void test()");
}
void test1() {
out.println("void test1()");
}
void test2() {
out.println("void test2()");
}
}
public class ClassLoaderJZ {
public static void main(String[] args) throws Exception {
// getMethod()方法获得所有public的方法包括从Object继承的方法
// for(Method m:aaa.class.getMethods()){
// out.println(m);
// };
// getDeclaredMethods()方法获得所有在本类中自己声明的方法
for (Method m : aaa.class.getDeclaredMethods()) {
out.println("输出方法的返回类型,参数类型,修饰符,以及方法的异常类型");
out.println(m.getReturnType());
out.println(m.getParameters().length);
out.println(m.getModifiers());
for (Class c : m.getExceptionTypes()) {
out.println(m);
}
}
}
}
输出结果:
输出方法的返回类型,参数类型,修饰符,以及方法的异常类型
void
0
0
void com.study.test.aaa.test() throws java.lang.Exception
输出方法的返回类型,参数类型,修饰符,以及方法的异常类型
void
0
0
输出方法的返回类型,参数类型,修饰符,以及方法的异常类型
void
0
0
七、通过反射调用方法
package com.study.test;
import static java.lang.System.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
interface I1 {
}
interface I2 {
}
class aaa implements I1, I2 {
public aaa() {
out.println("aaa()");
}
public aaa(int i) {
out.println("aaa(int i)");
}
protected aaa(int i, int j) {
out.println("aaa(int i,String j)");
}
public void test() {
out.println("void test()");
}
public void test1(int i) {
out.println("void test1()");
}
void test2(int j, int k) {
out.println("void test2()");
}
}
public class ClassLoaderJZ {
public static void main(String[] args) throws Exception {
// getMethod()方法获得所有public的方法包括从Object继承的方法
// for(Method m:aaa.class.getMethods()){
// out.println(m);
// };
// getDeclaredMethods()方法获得所有在本类中自己声明的方法
out.println("获得所有在本类中自己声明的方法");
for (Method m : aaa.class.getDeclaredMethods()) {
out.println(m);
}
// 注意:遍历出的构造函数是无序的
out.println("构造函数");
for (Constructor c : aaa.class.getDeclaredConstructors()) {
out.println(c);
}
out.println("方法调用");
aaa.class.getDeclaredMethods()[0].invoke(aaa.class.getDeclaredConstructors()[2].newInstance(), null);
aaa.class.getDeclaredMethods()[1].invoke(aaa.class.getDeclaredConstructors()[1].newInstance(1), 1);
}
}
输出结果:
获得所有在本类中自己声明的方法
public void com.study.test.aaa.test()
public void com.study.test.aaa.test1(int)
void com.study.test.aaa.test2(int,int)
构造函数
protected com.study.test.aaa(int,int)
public com.study.test.aaa(int)
public com.study.test.aaa()
方法调用
aaa()
void test()
aaa(int i)
void test1()
八、反射得到所有的字段
package com.study.test;
import static java.lang.System.out;
import java.io.IOException;
import java.lang.reflect.Field;
class aa {
private int j = 2;
public static int i = 1;
void test1(int i) throws Exception, IOException {
out.println("test");
}
public static int test2() {
out.println("test1");
return 1;
}
}
public class ClassLoaderJZ {
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException,
IllegalAccessException, InstantiationException {
// 得到第一个字段内容
Field f1 = aa.class.getDeclaredField("j");
f1.setAccessible(true);
out.println(f1.get(aa.class.newInstance()));
// 得到第二个字段内容
out.println(aa.class.getDeclaredField("i").get(null));
}
}
输出结果:
2
1