JAVA反射初探

本文详细介绍了Java反射机制的概念及其在运行时动态获取类信息和调用方法的能力。通过三种方式获取Class对象,包括从对象、类名字符串及Class类的forName方法。接着,展示了如何获取和操作类的字段、方法,包括私有成员的访问。最后讨论了Java中泛型Class、T与Class的区别,并解释了方法中使用T的原因。
摘要由CSDN通过智能技术生成


一、JAVA反射是什么?

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象。


二、使用说明

1.获取Class对象的三种方式

1.1第一种方式

Object ——> getClass()

		Blog blog = new Blog();
		Class blogClass1 = blog.getClass();
		System.out.println(blogClass1.getName());

1.2第二种方式

任何数据类型(包括基本数据类型)都有一个“静态”的class属性

		Class<Blog> blogClass2 = Blog.class;
		System.out.println(blogClass2 == blogClass1);

1.3第三种方式

通过Class类的静态方法:forName(String className)(常用)

		Class blogClass3 = Class.forName("org.springblade.test.entity.Blog");
		System.out.println(blogClass3 == blogClass2);

2.获取字段

2.1获取所有公有的字段

		Field[] fieldArray = blogClass3.getFields();
		for (Field f : fieldArray) {
			System.out.println(f);
		}

2.2获取所有的字段(包括私有、受保护、默认的)

		fieldArray = blogClass3.getDeclaredFields();
		for (Field f : fieldArray) {
			System.out.println(f);
		}

2.3获取公有字段**并调用

		Field f = blogClass3.getField("blogTitle");
		System.out.println(f);
		//获取一个对象 //产生Blog对象--》Blog blog = new Blog();
		Blog blog1 = blogClass2.getConstructor().newInstance();
		//为字段设置值 //为Blog对象中的blogContent属性赋值--》blog.blogContent = "陈奕迅"
		f.set(blog1, "陈奕迅");
		//验证
		System.out.println("验证姓名:" + blog1.getBlogTitle());

2.4获取私有字段**并调用

		f = blogClass3.getDeclaredField("blogContent");
		System.out.println(f);
		//暴力反射,解除私有限定
		f.setAccessible(true);
		f.set(blog1, "张学友");
		System.out.println("验证:" + blog1);

3.获取方法

3.1获取所有的公有方法

		blogClass3.getMethods();
		Method[] methodArray = blogClass3.getMethods();
		for (Method m : methodArray) {
			System.out.println(m);
		}

3.2获取所有的方法,包括私有的

		methodArray = blogClass3.getDeclaredMethods();
		for (Method m : methodArray) {
			System.out.println(m);
		}

3.3获取公有的setBlogTitle()方法

		Method m = blogClass2.getMethod("setBlogTitle", String.class);
		System.out.println(m);
		//实例化一个Blog对象
		Object obj = blogClass2.getConstructor().newInstance();
		m.invoke(obj, "获取公有的setBlogTitle()方法");
		System.out.println(obj);

3.4获取私有的setBlogContent()方法

		m = blogClass2.getDeclaredMethod("setBlogContent", String.class);
		System.out.println(m);
		//解除私有限定
		m.setAccessible(true);
		//需要两个参数,一个是要调用的对象(获取有反射),一个是实参
		m.invoke(obj, "获取私有的setBlogContent()方法");
		System.out.println("返回值:" + obj);

4.Java中泛型Class< T >、T与Class< ? >

4.1区别

单独的 T 代表一个类型 ,而 Class< T >代表这个类型所对应的类, Class< ? >表示类型不确定的类

 E - Element (在集合中使用,因为集合中存放的是元素)
 T - TypeJava 类)
 K - Key(键)
 V - Value(值)
 N - Number(数值类型)
 ? -  表示不确定的java类型

举例说明: 
Set<T> 表示 集合里 是   T类的实例 
List<E> 表示  集合里 是  E类的实例 
List<?> 表示 集合里的对象类型不确定,未指定 
ListList<?> 是一样的。 

泛型的作用: 
1、用泛型: 
List<T> list = new ArrayList<T>();  
T t = list.get(0);  

2、不用泛型: 
List  list = new ArrayList();  
T t = (T)list.get(0);

4.2如何创建一个Class< T >类型的实例

就像使用非泛型代码一样,有两种方式:调用方法 Class.forName() 或者使用类常量X.classClass.forName() 被定义为返回 Class<?>。
另一方面,类常量 X.class 被定义为具有类型 Class<X>。
所以 String.classClass<String> 类型的。

4.3方法中为什么需要< T > T修饰

泛型的声明,必须在方法的修饰符(public,static,final,abstract等)之后,返回值声明之前。

public static <T> T demo(HttpServletRequest request,Class<T> clazz){}

其中第一个是与传入的参数Class相对应的,相当于返回值的一个泛型,后面的T是返回值类型,代表方法必须返回T类型的(由传入的Class决定)


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-.- !

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值