java反射的使用,java反射如何通俗易懂理解
Yyds干货库存
(1)什么是反思?
反射是将Java类的组件映射到Java对象中。即在运行状态下,可以获得任何类的所有属性和方法;对于任何对象,您都可以调用它的任何方法和属性。这种动态获取信息,动态调用对象方法的功能被称为Java反射机制。
注意:类加载后,在堆内存的方法区生成一个类对象(一个类只有一个类对象),这个对象包含完整的类结构信息。你可以通过这个对象查看对应类的所有信息。
(2)反思能做什么?
(1)在运行时判断任意对象所属的类
(2)在运行时构造任何类的对象
(3)运行时判断任意类的成员变量和方法。
(4)在运行时获取通用信息。
(5)运行时调用任何对象的成员变量和方法。
(6)在运行时处理注释。
(7)生成动态代理。
(3)阶级阶级
可以通过对象获得的信息:类的属性、方法和构造函数,以及类实现的接口。对于每个类,JRE都为它保留了一个常量类类型的对象。类对象包含关于特定结构(类/接口/枚举/注释/基元类型/void/[])的信息。
(1)阶级本身也是阶级。
(2)类对象只能由系统创建。
(3)一个加载的类在JVM中只会有一个类实例。
(4)类对象对应于加载到JVM中的. Class文件。
(5)每个类实例都会记住是哪个类实例生成的。
(6)一个类中所有加载的结构完全可以通过Class获得。
(7)阶级阶级是反思的根源。对于任何您想要动态加载和运行的类,您必须首先获得相应的类对象。
(四)实际应用一、获取类class I实例的方法:调用运行时类的属性
方法二:通过运行时类的对象调用getClass()。
方法3:调用Class:format name(String Class path)的静态方法
模式4:使用类的加载器:ClassLoader。
@测试
Public Voidtest3()抛出ClassNotFoundException {//获取运行时类的方法(前三个是重点)
//方法一:调用运行时类的属性。
Class clazz=Person.class
system . out . println(clazz);
//方法二:通过运行时类的对象调用getClass()。
人员p1=新人员();
class clazz 2=P1 . getclass();
system . out . println(clazz 2);
//模式三:调用Class的静态方法:formatName(String classPath)
class claz 3=class . forname( practice。人’);
system . out . println(clazz 3);
//确定它们是否相等。
system . out . println(clazz==clazz 2);
system . out . println(claz 2==claz 3);
//说明:更好的体现了动态性,编译时无法判断错误。一旦运行,它会直接报告错误。
//模式4;使用类的加载器:ClassLoader
class loader class loader=reflection test . class . get class loader();
class claz 4=class loader . load class( practice。人’);
system . out . println(clazz 4);
system . out . println(claz 3==claz 4);
}补充:
(1)哪些对象可以有类实例?
类:外部类、成员(成员内部类、静态内部类)、局部内部类、匿名内部类。
接口:接口
[]:数组
枚举:枚举
批注:批注@接口
原始类型:基本数据类型
无效
(2)类加载器
二。读取配置文件的基本介绍(属性):
Java中的属性文件是一个配置文件,主要用来表达配置信息。文件类型是*。属性,格式为文本文件。文件的内容采用“键=值”的格式。
@测试
public void test1()引发异常{
Properties pros=new Properties();
//此时文件的默认路径在当前模块下。
//您也可以使用完整路径在特定位置查找属性文件
//file inputstream fis=new file inputstream( src \ \ practice \ \ JDBC 1 . properties );
文件输入流fis=新文件输入流( JDBC。属性’);
亲。负载(fis);
字符串user=pros。getproperty( user );
字符串密码=pros。getproperty(“password”);
系统。出去。println( user= user \ n password= password);
}
/**
* 读取配置文件(方式二)
* */
@测试
公共void测试3()引发异常{
Properties pro S3=新属性();
class loader class loader=classloadertest。班级。获取类加载器();
//使用绝对路径
InputStream is=class loader。getresourceasstream( src \ \ practice \ \ JDBC 1。属性’);
优点3。负载(是);
字符串名称=亲S3。getproperty( user );
字符串密码=亲S3。getproperty(“password”);
System.out.println(user= name ,password= password);
}三。创建运行时类的对象newInstance():调用此方法,创建运行时类的对象,内部调用了运行时类的空参构造器此方法使用前提:(1)运行时类必须提供空参构造器(2)空参构造器的访问权限必须要够,通常为公共在javabean中要求提供一个公众的的空参构造器原因如下:(1) 便于通过反射,创建运行时类的对象(2) 便于子类继承此运行时类的对象,默认调用超级()时,保证父类由此构造器公共类NewInstanceTest {
@测试
公共void test2()引发InstantiationException,IllegalAccessException {
//(1)获取运行时类
Class Person clazz=Person.class
//(2)方法1 - newInstance():调用此方法,创建对应的运行时类的对象(调用了运行时类的空参构造器)
object obj=clazz。新实例();
系统。出去。println(obj);
}
}四。获取运行时类的完整结构.实现的全部接口
公共课?[]获取接口()
说明:确定此对象所表示的类或接口实现的接口。
具体代码:
@测试
公共void test3(){
clazz类=人1。类;
class[]接口=clazz。获取接口();
对于(f类:接口){
系统。出去。println(f);
}
系统。出去。println();
//获取运行时类父类的接口
class[]接口1=clazz。获取超类().获取接口();
对于(m类:接口1){
系统。出去。println(m);
}
}.所继承的父类
公共课?Super T getSuperclass()
说明:返回表示此班级所表示的实体(类、接口、基本类型)的父类的
班级。
/**
* 获取运行时类的父类
* */
@测试
公共void test7(){
clazz类=人1。类;
类超级System.out.println(超类);
}
/**
* 通过反射获取带泛型的父类
* */
@测试
public void test8(){
clazz类=人1。类;
类型通用
ParameterizedType ParameterizedType=(ParameterizedType)generiSuperclass;
//获取泛型类型
type[]实参=参数化类型。getactualtypearguments();
系统。出去。println(实际参数[0]).getTypeName());
}.全部的构造器
公共构造函数T [] getConstructors()
说明:返回此班级对象所表示的类的所有公众的构造方法。
公共构造函数T [] getDeclaredConstructors()
说明:返回此班级对象表示的类声明的所有构造方法。
构造器类中
public int get修饰符();-说明:取得修饰符
公共字符串getName();-说明:取得方法名称
公共课?[]getParameterTypes();-说明:取得参数的类型
代码实现:
@测试
公共void test1()抛出NoSuchMethodException {
clazz类=人1。类;
//getConstructors():获取当前运行时类中声明为公众的的方法
constructor[]constructors=clazz。获取构造函数();
对于(构造函数e:构造函数){
系统。出去。println(e);
}
系统。出去。println();
//getDeclaredConstructor():获取当前类中所有声明的构造器
constructor[]声明constructors=clazz。getdeclaredconstructors();
对于(构造函数e:声明重建者){
系统。出去。println(e);
}
}.全部的方法
公共方法[] getDeclaredMethods()
说明:返回此班级对象所表示的类或接口的全部方法
公共方法[] getMethods()
说明:返回此班级对象所表示的类或接口的公众的的方法
方法类中:
公共课?getReturnType()
说明:取得全部的返回值
公共课?[]getParameterTypes()
说明:取得全部的参数
public int get修饰符();-取得修饰符
公共课?[]getExceptionTypes()取得异常信息
具体代码:
/**
* 权限修饰符数据类型变量名
* */
@测试
public void test2(){
clazz类=人1。类;
field[]declareFields=clazz。getdeclaredfields();
对于(字段女:声明字段){
系统。出去。println();
系统。出去。println(f);
//权限修饰符
int modifier=f . get modifiers();
//输出对应属性的权限及权限修饰符的等级
系统。出去。println(修饰符。tostring(修饰符));
System.out.println(修饰符);
//数据类型
class type=f . gettype();
系统。出去。println(类型 \ t );
//变量名
string name=f . getname();
System.out.println(名称);
}
}
.全部的田
公共字段[]获取字段();
说明:返回此班级对象所表示的类或接口的公众的的字段。
公共字段[]getDeclaredFields();
说明:返回此班级对象所表示的类或接口的全部字段。
田方法
public int get修饰符();
说明:以整数形式返回此田的修饰符。
公共课?getType();
说明:得到田的属性类型
公共字符串getName()
说明:返回田的名称
具体代码
@测试
公共void test1(){
clazz类=人1。类;
//获取属性结构
//getFields():获取当前运行时类及父类中声明为公众的访问权限的属性
field[]field=clazz。获取字段();
对于(字段女:字段){
系统。出去。println(f);
}
系统。出去。println();
//getDeclareFields():获取当前运行时类中声明的所有属性。(不包含父类中声明的属性)
field[]declareFields=clazz。getdeclaredfields();
对于(字段女:声明字段){
系统。出去。println(f);
}
}.注释相关
获取注释(类T注释类)
getDeclaredAnnotations()
代码实现:
@测试
public void test9(){
clazz类=人1。类;
批注[]批注=clazz。获取批注();
对于(批注学生:批注){
系统。出去。println(s);
}
}.泛型相关
类型getGenericSuperclass()
说明:获取父类泛型类型
参数化类型
说明:泛型类型
getActualTypeArguments()
说明:获取实际的泛型类型参数数组
.类所在的包
包getPackage()
代码实现
@测试
公共void test5(){
clazz类=人1。类;
包包=clazz。get package();
系统。出去。println(pack);
}
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。