Java中的反射

1.反射是什么,有什么作用?

            反射---在程序运行的过程中,我们可以得到某个类的对象,可以调用某个类中的任何一个变量/方法,
    这种动态获取信息的过程就是反射。

    当我们在没有见过某个类的情况下,仅凭一个完整的类名,就可以获取到整个类的所有信息。

    反射的使用场景:

         1.jdbc加载数据库驱动

         2.Servlet的web.xml配置

         3.Spring框架

2.实例对象与反射对象的相互转换?

    实例对象-----就是我们通过类创建的对象

    反射对象-----通过反射机制得到的类对象

        例如:  反射就是一面镜子,镜子前面的你就是实例对象,通过镜子得到的镜子里面的你就是反射对象。

    反射对象是一个Class类型的对象
    Class---不是创建类的关键字,表示一个类,所以反射对象是一个Class类型的对象
     public final class Class<T>

    1.通过实例对象得到反射对象

package com.wangxing.test1;
public class TestMain {

	public static void main(String[] args) {
		// 得到反射对象 
		// 1.通过实例对象得到反射对象[实例对象的getClass()方法]
		Student stu = new Student();
		Class stuClass = stu.getClass();
		// 2.通过Class类的forName(包名.类名)——括号内的参数是包名+类名书写格式是包名.类名
		try {
			Class stuClass2 = Class.forName("com.wangxing.test1.Student");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

    2.通过反射对象得到实例对象

package com.wangxing.test1;
public class TestMain {

	public static void main(String[] args) {
		// 通过反射对象得到实例化对象【反射对象的newInstance()方法】
		// 用这个方法得到的实例化对象是Object类型的,要进行类型转换
		try {
			Class stuclass2 = Class.forName("com.wangxing.test1.Student");
			Student stu2 = (Student) stuclass2.newInstance();
			stu2.test1();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

3.通过反射对象得到构造方法\成员变量\成员方法

Constructor<?>[]

getConstructors() 得到构造方法

Field[]

getDeclaredFields() 得到成员变量

Method[]

getDeclaredMethods() 得到成员方法

Class<?>[]

getInterfaces() 得到接口。

Class<? super T>

getSuperclass() 得到父类。

Package

getPackage() 得到包对象。

int

getModifiers() Java语言修饰符

Modifier的toString(int mod)

String

getName() 得到类名称

4.反射的应用

package com.wangxing.test1;
public class Student extends Person implements MyTestInterface {
	
	private String stuname;
	private int stuage;
	public Student(){}
	public Student(String name,int age){
		this.stuname=name;
		this.stuage=age;
	}
	public void test1(){
		System.out.println("Student类的无参实例方法");
	}
	public String testString (String args){
		return "hello";
	}
}

根据类名还原上面的类

package com.wangxing.test1;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
//通过反射得到与Studnet类一样的java类
public class TestMain2 {
	// 因为获得类名时,会连包名一起获得,所以自己创建一个截取类名的方法
	public static String testName(String classname) {
		return classname.substring(classname.lastIndexOf(".") + 1);
	}

	public static void main(String[] args) throws Exception {
		// 得到反射对象
		Class stuclass1 = Class.forName("com.wangxing.test1.Student");
		// 得到包的定义
		// 得到Student类的包名
		// 通过getPackage()方法得到包对象,再通过getName()方法获得包名
		String pagename = stuclass1.getPackage().getName();
		String packageinfo = "package" + pagename + ";";
		System.out.println(packageinfo);
		// 得到Student类的定义
		// 类的修饰符
		// 通过getModifiers()方法得到修饰符对应的数字。再通过Modifier.toString(int a)方法转换为字符串
		String classxiushifu = Modifier.toString(stuclass1.getModifiers());
		// 类名
		String leiming = testName(stuclass1.getName());
		// 得到父类的类名
		// 先通过getSuperclass()方法得到父类反射对象,再通过getName()得到父类类名
		String supername = testName(stuclass1.getSuperclass().getName());
		// 得到接口的名称
		// 通过getInterfaces()方法得到所有被实现的接口的反射对象。放在数组中
		Class interfacerr[] = stuclass1.getInterfaces();
		// 创建StringBuilder对象处理字符串,因为多个接口时要考虑追加的问题
		StringBuilder interinfo = new StringBuilder();
		for (Class inter : interfacerr) {
			String intername = testName(inter.getName());
			// 多个接口时,都是跟随在后面,用逗号隔开的。故用来处理字符串的类要可追加的
			interinfo.append(intername + ",");
		}
		// 最后一个接口后面多一个逗号,所以要删除
		interinfo.deleteCharAt(interinfo.length() - 1);
		String classinfo = classxiushifu + " class " + leiming + " extends " + supername + " implements "
				+ interinfo.toString() + " {";
		System.out.println(classinfo);
		// 得到类中的成员变量
		// 得到所有成员变量,并保存在数组中
		Field fieldarr[] = stuclass1.getDeclaredFields();
		// 循环遍历成员变量
		for (Field field : fieldarr) {
			// 得到变量的修饰符
			String fieldxiushifu = Modifier.toString(field.getModifiers());
			// 得到变量类型名称
			// 先通过getType()方法获得类型对象,再通过getName()获得名称
			String fieldleixing = testName(field.getType().getName());
			// 得到变量名称
			String fieldname = field.getName();
			String fieldinfo = fieldxiushifu + " " + fieldleixing + " " + fieldname + ";";
			System.out.println("\t" + fieldinfo);
		}
		// 得到类中的构造方法
		// 得到所有构造方法,并保存在数组中
		Constructor constructorarr[] = stuclass1.getConstructors();
		// 循环遍历构造方法
		for (Constructor con : constructorarr) {
			// 得到构造方法的修饰符
			String conxiu = Modifier.toString(con.getModifiers());
			// 得到构造方法的名称
			String conname = testName(con.getName());
			// 构造方法中的参数可能有多个,并用逗号隔开。所以创建
			// StringBuilder对象来处理字符串,使其可以追加
			StringBuilder canshu = new StringBuilder();
			// 得到所有的参数类型,并保存入数组
			Class contype[] = con.getParameterTypes();
			// 这里必须判断保存所有参数的数组大小,若=0,就会出现下面异常
			// java.lang.StringIndexOutOfBoundsException: String index out of
			// range: -1
			if (contype.length != 0) {
				for (Class typeclass : contype) {
					// 得到参数的类型名称
					String typename = testName(typeclass.getName());
					// 将所有参数拼接起来
					canshu.append(typename + " name,");
				}
				// 最后一个参数后面会多一个逗号,所以要删掉
				canshu.deleteCharAt(canshu.lastIndexOf(","));
			}
			String coninfo = conxiu + " " + conname + "(" + canshu.toString() + "){}";
			System.out.println("\t" + coninfo);
		}
		// 得到实例方法
		// 得到所有实例方法,并保存在数组中
		Method methodarr[] = stuclass1.getDeclaredMethods();
		// 循环遍历
		for (Method meth : methodarr) {
			// 得到实例方法的修饰符
			String methxiu = Modifier.toString(meth.getModifiers());
			// 得到返回类型的名称
			String methreturn = testName(meth.getReturnType().getName());
			// 得到方法名称
			String methname = meth.getName();
			// 实例方法中的参数可能有多个,并用逗号隔开。所以创建
			// StringBuilder对象来处理字符串,使其可以追加
			StringBuilder canshu = new StringBuilder();
			// 得到所有的参数类型,并保存入数组
			Class methodcanshutype[] = meth.getParameterTypes();
			// 这里必须判断保存所有参数的数组大小,若=0,就会出现下面异常
			// java.lang.StringIndexOutOfBoundsException: String index out of
			// range: -1
			if (methodcanshutype.length != 0) {
				for (Class typeclass : methodcanshutype) {
					String typename = testName(typeclass.getName());
					canshu.append(typename + "args,");
				}
				canshu.deleteCharAt(canshu.lastIndexOf(","));
			}
			String methodinfo = methxiu + " " + methreturn + " " + methname + "(" + canshu.toString() + "){}";
			System.out.println("\t" + methodinfo);
		}
		System.out.println("}");
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值