JavaSE系列-03 反射与泛型

本文深入探讨Java反射机制,包括Class类的使用、获取字段、调用方法、构造方法及继承关系。同时,详细解析泛型的概念、使用、擦拭法、通配符以及泛型与反射的关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

反射

Class类

class本身是一种数据类型(Type),class/interface的数据类型是Class,JVM为每个加载的class创建唯一的Class实例。
Class实例包含该class的所有信息,通过Class实例获取class信息的方法称为反射(Reflection)

获取一个class的Class实例:
	1)Class cls = String.class;
	2)Class cls = "str".getClass();
	3)Class cls = Class.forName("java.lang.String");
注意 Class的==比较和instanceof的区别
Integer n = new Integer(123);

boolean b3 = n instanceof Integer; // true
boolean b4 = n instanceof Number; // true

// 精确判断时
boolean b1 = n.getClass() == Integer.class; // true
boolean b2 = n.getClass() == Number.class; // false
从Class实例获取class信息:
	1)getName():获取完整类名
	2)getSimpleName():获取简单的类名
	3)getPackage():获取包名
从Class实例判断class类型:
	1)isInterface():判断是否是接口类型
	2)isEnum():判断是否是枚举类型
	3)isArray():判断是否是数组类型
	4)isPrimitive():判断是否是基本类型
创建class实例:
	cls.newInstance()
	JVM总是动态加载class,可以在运行期根据条件控制加载class
// commons logging优先使用Log4j
LogFactory factory;
if(isClassPresent("org.apache.logging.log4j.Logger")){
   
   
	factory = createLog4j();
}else{
   
   
	factory = createJdkLog();
}
boolean isClassPresent(String name){
   
   
	try{
   
   
		Class.forName(name);
		return true;
	}catch(Exception e){
   
   
		return false;
	}
}

访问字段

通过Class实例获取字段field信息:
	1)getField(name)——获取某个public的field(包括父类)
	2)getDeclaredField(name)——获取当前类的某个field(不包括父类)
	3)getFields()——获取所有public的field(包括父类)
	4)getDeclaredFields()——获取当前类的所有field(不包括父类)
Field对象包含一个field的所有信息
	1)getName():字段名称
	2)getType():字段定义的数据类型
	3)getModifiers():字段修饰符
获取和设置field的值
	1)get(Object obj)
	2)set(Object, Object)
通过反射访问Field需要通过SecurityManager设置的规则
通过设置setAccessible(true)来访问非public字段

调用方法

通过Class实例方法获取Method信息:
	1)getMethod(name, Class ...):获取某个public的method(包括父类)
	2)getDeclaredMethod(name, Class ...):获取当前类的某个method(不包括父类)
	3)getMethods():获取所有public的method(包括父类)
	4)getDeclaredMethods():获取当前类的所有method(不包括父类)
Method对象包含一个method的所有信息
	1)getName():获取方法名
	2)getReturnType():获取返回值类型
	3)getParameterTypes():获取方法参数类型
	4)getModifiers():获取方法修饰符
调用Method:
	Object invoke(Object obj, Object ...args)
通过设置setAccessible(true)来访问非public方法
反射调用Method也遵守多态的规则

调用构造方法

Class.newInstance()只能调用public无参数构造方法
	String s = (String) String.class.newInstance();	// ^_^
	Integer n = (Integer) Integer.class.newInstance();  // ERROR
通过Class实例获取Constructor信息:
	1)getConstructor(Class...):获取某个public 的 Constructor
	2)getDeclaredConstructor(Class...):获取某个Constructor
	3)getConstructors():获取所有public的Constructor
	4)getDeclareConstructors():获取所有的Constructor
通过Constructor实例可以创建一个实例对象
	newInstance(Object ... parameters)
通过设置setAccessible(true)来访问非public构造方法

获取继承关系

获取父类的Class:
	1)Class getSuperclass()
	2)Object的父类是null
	3)interface的父类是null
获取当前类直接实现的interface:
	1)Class[] getInterfaces()
	2)getInterfaces()获取的不包括间接实现的interface;如果想获取所有的,可以递归调用获取
	3)没有interface的class返回空数组
	4)interface返回继承的interface
判断一个向上转型是否成立:
	boolean isAssignableFrom(Class)

注解 Annotation

使用注解

注解是放在Java源码的类、方法、字段、参数前的一种标签
注解本身对代码逻辑没有任何影响,如何使用注解由工具决定
编译器可以使用的注解
	@Override:让编译器检查该方法是否正确实现了覆写
	@Deprecated:告诉编译器该方法已经标记为“作废”
	@SuppressWarnings:让编译器忽略警告
注解可以定义配置参数和默认值
	配置参数由注解类型定义
	配置参数可以包括:
		所有基本类型
		String
		枚举类型
		数组
	配置参数必须是常量

定义注解

使用@interface定义注解,例如
@Target(ElementType.METHOD)
public @interface Report {
   
   
	int type() default 0;
	String level() default "info";
	String value() default "";
}

使用元注解(meta annotation)定义注解
1)@Target
2)@Retention
3)@Repeatable
4)@Inherited

@Target
使用@Target定义Annotation可以被应用于源码的哪些位置:
	类或接口:ElementType.TYPE
	字段:ElementType.FIELD
	方法:ElementType.METHOD
	构造方法:ElementType.CONSTRUCTOR
	方法参数:ElementType.PARAMETER
@Retention
使用@Retention定义Annotation的生命周期
	仅编译器:RetentionRolicy.SOURCE
	仅class文件:RetentionRolicy.CLASS
	运行期:RetentionRolicy.RUNTIME
如果@Retention不存在,则该Annotation默认为CLASS
通常自定义的Annotation都是RUNTIME
@Repeatable
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

讲文明的喜羊羊拒绝pua

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

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

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

打赏作者

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

抵扣说明:

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

余额充值