JAVA学习笔记:java语言高级特性(反射Reflection)

反射Reflection

反射是JAVA中的一种机制,被称为java语言的反射机制,允许我们在代码动态获取类型中的相关信息和相关操作(方法等)

1、Class类型,java.lang.Class类–是java反射的入口
Class类是对java中所有类型的抽象而得到的一个类,即Class类类型对象可以表示java中任意一种类型。

每种类型在其加载到内存后,内存中都会产生一个与之对应的Class类类型的对象(有且只有一个),用来代表该类型。

每个类型都有且只有一个Class类类型的对象与之对应,通过这个Class类类型的对象我们就能获取该类型中的相关信息和操作。

例如:
1)Class类类型对象表示基本类型

Class cInt=int.class;
//isPrimitive()判断是否是原始类型即基本数据类型
System.out.println(cInt.isPrimitive);
//获取类型名
System.out.println(cInt.getName);

	//输出结果:
		true
		int

2)Class类类型对象表示类类型

Student stu=new Student();
//getClass()返回的是引用stu所指向的对象的实现类型的Class对象(获取Class类类型对象的一种方法)
Class cStu1=stu.getClass();
//直接通过类名.class获取Class类类型的对象(获取Class类类型的一种方法)
Class cStu2=Student.class;
;//都是Student类型,每种类型的Class类类型的对象只有一个
System.out.println(cStu1==cStu2)

//输出结果
true
Person p = new Student();
Class c1 = p.getClass();//c1表示Student类型
Class c2 = Person.class;//c2表示Person类型
//类型不同,他们的Class类类型对象也不同
System.out.println(c1 == c2);

输出结果
false

3)Class类类型的对象表示接口类型

	Action a = new Student();
			Class c1 = a.getClass();//c1表示Student类型,获取的是a引用所指向的对象类型的Class类型对象
			Class c2 = Action.class;//c2表示Action类型		
			System.out.println(c1 == c2);
			//isInterface判断是否是接口
			System.out.println(c1.isInterface());
			System.out.println(c2.isInterface());

输出结果:
false
false
true

4)Class类类型的对象表示数组类型

int[] a = new int[4];
			Class c1 = a.getClass();
			Class c2 = int[].class;
			System.out.println(c1 == c2);//true
			System.out.println(c1.isArray());//true

			Class c3 = c1.getComponentType();//c3表示该数组是使用什么类型声明出来的
			System.out.println(c3.getName());//int
			

			
			Student[] a = new Student[4];
			Class c1 = a.getClass();
			Class c2 = Student[].class;
			System.out.println(c1 == c2);//true
			System.out.println(c1.isArray());//true

			Class c3 = c1.getComponentType();//c3表示该数组是使用什么类型声明出来的
			System.out.println(c3.getName());//com.nc.test.Student类的全限定名

2、获取一个类类型的Class对象的三种方式
注:使用较多的数类类型的Class类型对象
1)使用类类型的对象调用getClass方法;getClass是Object中的final修饰的方法,每个对象都可以调用而且不能重写

Student s=new Student();
Class c=s.getClass();//获取的是s所指的类类型对象的Class类型对象

2)使用类型获取Class类型对象

Class c =Student.class;

3)使用Class类中的静态方法forName方法获取Class类型对象
注:这种方法比较灵活,只需要一个String类型的参数就行,String类型的参数为类的全限定名(包名+类名);此方法需要抛出异常

Class c=Class.forName("com.nc.test.Studnet");
//com.nc.test为Student类所在的包名

注:每种类型只有一个Class类类型的对象与之对应,所有不管用哪种方法,获取同一个类型的Class类型对象,使用==判断都是相等的;因为内存地址相同。

3、反射机制中常见的类

java.lang包下:
		Class  类		对java中所有类型抽象而得来的
		Package类		对java中所有包抽象而得来的

		java.lang.reflect包下:
		Modifier	类	对java中所有修饰符抽象而得来的
		Field		类	对java中所有属性抽象而得来的
		Method		类	对java中所有方法抽象而得来的
		Constructor 类	对java中所有构造器抽象而得来的
		Array		类	提供了对数组对象的动态访问
		ParameterizedType接口  在反射中表示参数化类型;例如:List<String> Point<Long,Long>等这种带泛型的类型
			

4、使用Class类型对象获取类中信息
1)获取该类所处的包的信信息;getPackage()方法获取包

Student s=new Student();
Class c=s.getClass();
System.out.println(c.getPackage().getName());//打印输出Class类型对象所对应Student类所在包的包名

2)获取该类的修饰符信息;getModifiers()获取修饰符

			//每个修饰符对应一个int值
			//如果有多个修饰符则int值相加
			Student s = new Student();
			Class c = s.getClass();
			System.out.println(c.getModifiers());//获取Class类型对象对应的Student类的修饰符

			System.out.println(Modifier.PUBLIC);//打印输出public修饰的int值
			System.out.println(Modifier.FINAL);//打印输出fianl修饰的int值

3)获取该类的名字

Student s = new Student();
Class c = s.getClass();
System.out.println(c.getName());//获取Class类型对象所对应的类Student类的类名(全限定名:包名+类名)

4)获取该类的父类的Class类型对象

Student s = new Student();
Class c = s.getClass();
//superclass表示其父类型的Class对象
Class superclass = c.getSuperclass();
//打印输出父类的名字
System.out.println(superclass.getName());

例如:

			Class c = Object.class;
			Class superclass = c.getSuperclass();
			System.out.println(superclass.getName());
			//运行报错,因为Object没有父类
			

例如:

			//判断c1是不是c2的子类型
			//判断c3是不是c2的子类型
			Class c1 = Student.class;
			Class c2 = Person.class;
			Class c3 = String.class
			System.out.println(c2.isAssignableFrom(c1));//true
			System.out.println(c2.isAssignableFrom(c3));//false

5)获取该类所实现的接口类型的Class类类型对象;getInterfaces()(接口是多实现,所有返回值是一个数组,存储接口的Class类类型的对象)

			Student s = new Student();
			Class c = s.getClass();
			//获取
			Class[] interfaces = c.getInterfaces();
			for(Class clazz:interfaces){
				System.out.println(clazz.getName());
			}

例如:

//判断c1是不是c2的实现类
			//判断c3是不是c2的实现类
			Class c1 = Student.class;
			Class c2 = Action.class;
			Class c3 = String.class
			System.out.println(c2.isAssignableFrom(c1));//true
			System.out.println(c2.isAssignableFrom(c3));//false

6)获得该类中所有属性
注:
getDeclaredFields()方法返回类中声明的属性,包括私有的
getFields()方法只返回类中public修饰的属性,包括继承的

例如:

Student s=new Student();
Class c=s.getClass();
//获取Class类型对应的Student类中声明的所有属性包括私有的,存到属性类Field数组中
Field[] delaredField=c.getgetDeclaredFields();
//使用for循环遍历数组
for(Field f:delaredField){
//	getModifiers()方法,获取属性的修饰符
	System.out.println(f.getModifiers());
//getType()获取属性的类型
	System.out.println(f.getType().getName());
//获取属性名
	System.out.println(f.getName());
	}

7)获得该类中所有的方法
注:
getDeclaredMethods()方法返回类中声明的方法,包括私有的
getMethods()方法只返回类中public修饰的方法,包括继承的

例如:

		Student s = new Student();
		Class c = s.getClass();
//获取Class类型对象所对应的类类型Student类中的所有方法,包括私有的,存到方法类Method的数组中
		Method[] declaredMethods = c.getDeclaredMethods();
//使用for循环遍历Method数组
		for(Method m:declaredMethods){
//getModifiers()获取方法的修饰符
				System.out.println(m.getModifiers());
//getReturnType()获取方法返回值类型
				System.out.println(m.getReturnType().getName());
//获取方法名
				System.out.println(m.getName());
//getParameterTypes()获取方法的参数类型
				System.out.println(Arrays.toString(m.getParameterTypes()));
//getExceptionTypes()获取方法的异常类型
				System.out.println(Arrays.toString(m.getExceptionTypes()));
		}

8)获取类中所有构造器
注:
getDeclaredConstructors()方法返回类中所有构造器
getConstructors()方法只返回类中public修饰的构造器

Student s = new Student();
	Class c = s.getClass();
//getDeclaredConstructors()获取Class类型对象所对应的类类型Student类的所有构造器,存入构造器类Constructor的数组中
	Constructor[] declaredConstructors = c.getDeclaredConstructors();
//循环遍历Constructor构造器类型的数组
	for(Constructor con:declaredConstructors){
//getModifiers()获构造器的修饰符
		System.out.println(con.getModifiers());
//获取构造器名
		System.out.println(con.getName());
//getParameterTypes()获取构造器参数类型
		System.out.println(Arrays.toString(con.getParameterTypes()));
//getExceptionTypes()获取构造器异常类型
		System.out.println(Arrays.toString(con.getExceptionTypes()));
			}

9)了解
—获得父类型中的泛型的真实类型
因为泛型类的泛型参数在编译期会被擦除,所以我们不能在运行期间直接拿到该泛型的实际类型,但是可以通过子类的Class对象来获取父类的泛型类型。
—获得类中的注解
使用反射也可以获得类中的注解.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值