Java反射机制,java中的反射机制使用
写爬虫互联网协议(互联网协议)被封了怎么解决?立即使用
一、什么是爪哇岛的反射机制(推荐:java视频教程)
爪哇反射是爪哇被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时透过反射应用程序接口取得任何一个已知名称的班级的内部信息,包括其修饰符(诸如公共、静态等)、超类(例如对象),实现之接口(例如可克隆的),也包括田地(复数);场;域;字段和方法的所有信息,并可于运行时改变田地(复数);场;域;字段内容或唤起方法。
爪哇反射机制容许程序在运行时加载、探知、使用编译期间完全未知的班级。
换言之,Java可以加载一个运行时才得知名称的类,获得其完整结构。
二、JDK中提供的反射应用程序接口
爪哇反射相关的应用程序接口在包java.lang.reflect中,JDK 1.6.0的显示包如下图:
Member接口 | 该接口可以获取有关类成员(域或者方法)后者构造函数的信息。 |
AccessibleObject类 | 该类是域(field)对象、方法(method)对象、构造函数(constructor)对象的基础类。它提供了将反射的对象标记为在使用时取消默认 Java 语言访问控制检查的能力。 |
Array类 | 该类提供动态地生成和访问JAVA数组的方法。 |
Constructor类 | 提供一个类的构造函数的信息以及访问类的构造函数的接口。 |
Field类 | 提供一个类的域的信息以及访问类的域的接口。 |
Method类 | 提供一个类的方法的信息以及访问类的方法的接口。 |
Modifier类 | 提供了 static 方法和常量,对类和成员访问修饰符进行解码。 |
Proxy类 | 提供动态地生成代理类和类实例的静态方法。 |
爪哇反射机制提供如下功能:
在运行时判断任意一个对象所属的类
在运行时构造任意一个类的对象
在运行时判段任意一个类所具有的成员变量和方法
在运行时调用任一个对象的方法
在运行时创建新类对象
在使用爪哇的反射功能时,基本首先都要获取类的班级对象,再通过班级对象获取其他的对象。
这里首先定义用于测试的类:
类别类型{
public int公共字段
公共字符串公共字段
私有int prvIntField
公共类型(){
日志(“默认构造函数");
}
Type(int arg1,String arg2){
pubIntField=arg1
pubStringField=arg2
日志(“带参数的构造函数");
}
public void setIntField(int val) {
this.prvIntField=val
}
public int getIntField() {
返回prvIntField
}
私有空的日志(字符串消息){
系统。出去。println( Type: msg );
}
}
类扩充形式扩展类型{
public int pubIntExtendField
公共字符串publistringextendfield
private int prvIntExtendField
公共ExtendType(){
日志(“默认构造函数");
}
ExtendType(int arg1,String arg2){
pubIntExtendField=arg1
pubStringExtendField=arg2
日志(“带参数的构造函数");
}
public void setIntExtendField(int field 7){
this.prvIntExtendField=field7
}
public int getintextendenfield(){
返回prvIntExtendField
}
私有空的日志(字符串消息){
系统。出去。println( ExtendType: msg );
}
} 1、获取类的班级对象
班级类的实例表示正在运行的爪哇应用程序中的类和接口。获取类的班级对象有多种方式:
调用getClass:
布尔变量1=真;
班级?类别类型2=变量1。getclass();
系统。出去。println(类类型2);运用。班级语法:
班级?类别类型4=布尔型。类;
系统。出去。println(类类型4);运用静态方法Class.forName():
班级?类别类型5=类别。forname( Java。郎。布尔);
系统。出去。println(类类型5);运用原始包装类的类型语法:
这里返回的是原生类型,和布尔型返回的不同
班级?类别类型3=布尔值。类型;
系统。出去。println(类类型3);2、获取类的菲尔茨
可以通过反射机制得到某个类的某个属性,然后改变对应于这个类的某个实例的该属性值JAVA .的ST级类提供了几个方法获取类的属性。
public Field getField(String name) | 返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段 |
public Field[] getFields() | 返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段 |
public Field getDeclaredField(String name) | 返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段 |
public Field[] getDeclaredFields() | 返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段 |
//使用获取字段获取属性
field[]fields=类类型。获取字段();
对于(字段女:字段)
{
系统。出去。println(f);
}
系统。出去。println();
//使用getDeclaredFields获取属性
字段=类类型。getdeclaredfields();
对于(字段女:字段)
{
系统。出去。println(f);
}输出:
可见获取字段和getDeclaredFields区别:
获取字段返回的是申明为公众的的属性,包括父类中定义,
GetDeclaredFields返回指定类定义的所有已定义属性,不包括父类的。
3.获取该类的方法
通过反射机制得到一个类的方法,然后调用这个类的一个实例对应的方法。
ClassT类提供了几个方法来获取该类的方法。
公共方法getMethod(字符串名,类?parameterTypes)返回一个Method对象,该对象反映由此类对象表示的类或接口的指定公共成员方法。
Public Method[] getMethods()返回一个包含一些方法对象的数组,这些方法对象反映了这个类对象所代表的类或接口的公共成员方法(包括类或接口声明的方法和从超类和接口继承的方法)。
公共方法getDeclaredMethod(字符串名,类?parameterTypes)返回一个Method对象,该对象反映由该类对象表示的类或接口的指定声明方法。
Method [] getDeclaredMethods()返回一个方法对象数组,该数组反映了由该类对象表示的类或接口声明的所有方法,包括公共、受保护、默认(包)访问和私有方法,但不包括继承的方法。
//使用getMethods获取函数
班级?classType=ExtendType.class
method[]methods=class type . get methods();
for(方法m:方法)
{
system . out . println(m);
}
system . out . println();
//使用getDeclaredMethods获取函数
methods=class type . getdeclaredmethods();
for(方法m:方法)
{
system . out . println(m);
}输出:
4.获取该类的构造函数。
通过反射机制获取类的构造函数,然后调用构造函数创建类的实例。
ClassT类提供了几种方法来获取类的构造函数。
public constructor get constructor(类。parameterTypes)返回一个Constructor对象,该对象反映由此Class对象表示的类的指定公共构造函数。
公共构造函数?[] getConstructors()返回包含一些构造函数对象的数组,这些构造函数对象反映了这个类对象所代表的类的所有公共构造函数方法。
public constructor getDeclaredConstructor(类?parameterTypes)返回一个Constructor对象,该对象反映由此类对象表示的类或接口的指定构造方法。
公共构造函数?[] getDeclaredConstructors()返回一个构造函数对象数组,该数组反映了该类对象所代表的类声明的所有构造函数方法。它们是公共的、受保护的、默认的(包)访问和私有的构造方法。
//使用getConstructors获取构造函数
建造师?[]constructors=class type . get constructors();
for(构造函数?m:构造函数)
{
system . out . println(m);
}
system . out . println();
//使用getDeclaredConstructors获取构造函数
constructors=class type . getdeclaredconstructors();
for(构造函数?m:构造函数)
{
system . out . println(m);
}
输出:
public com.quincy.ExtendType()
public com.quincy.ExtendType()
Com.quincy.extendtype (int,java.lang.string) 5。创建一个新类的实例。
有几种方法可以通过反射机制创建一个新类的实例。
不带参数调用ctor:
1.调用类的类对象的newInstance方法,该方法将调用对象的默认构造函数。如果没有默认构造函数,调用将失败。
班级?classType=ExtendType.class
object inst=class type . new instance();
system . out . println(inst);输出:
2.调用默认构造函数对象的newInstance方法。
班级?classType=ExtendType.class
建造师?constructor 1=class type . get constructor();
object inst=constructor 1 . new instance();
system . out . println(inst);输出:
用参数调用ctor:
3.用参数调用构造函数对象的newInstance方法。
建造师?构造者2=
class type . getdeclaredconstructor(int . class,string . class);
object inst=constructor 2 . new instance(1, 123 );
system . out . println(inst);输出:
6.调用类的函数。
通过反射获取方法对象,调用字段的Invoke方法调用函数。
班级?classType=ExtendType.class
object inst=class type . new instance();
方法Log method=class type . strong getdeclaredmethod/strong( Log ,string . class);
logMethod.invoke(inst, test );
输出:
类型:默认构造函数
ExtendType:默认构造函数
font color= # ff 0000 Class com . Quincy . Class t不能使用修饰符 private/font访问com.quincy.ExtendType类的成员
Font= # ff0000 上述失败是由于缺少调用私有函数的权限。此处需要将Accessible设置为true/font
班级?classType=ExtendType.class
object inst=class type . new instance();
方法Log method=class type . getdeclaredmethod( Log ,string . class);
font color= # ff 0000 log method . set accessible(true);/font
logMethod.invoke(inst, test );7.设置/获取类的属性值。
通过反射获取类的Field对象,调用Field方法设置或获取值。
班级?classType=ExtendType.class
object inst=class type . new instance();
field int field=class type . getfield( pubintexendfield );
int field . strong setint/strong(inst,100);
int value=int field . strong getint/strong(inst);四。动态创建代理类
代理模式:代理模式的功能=为其他对象提供代理,以控制对该对象的访问。
代理模式的作用:
抽象角色:声明真实对象和代理对象之间的公共接口。
代理角色:代理角色包含对真实对象的引用,因此您可以操作真实对象。
真实角色:代理角色所代表的真实对象就是我们最终要引用的对象。
动态代理:
java.lang.reflect.Proxy
Proxy提供了创建动态代理类和实例的静态方法,它也是由这些方法创建的所有动态代理类的超类。
InvocationHandler:
是由代理实例的调用处理程序实现的接口,每个代理实例都有一个关联的调用处理程序。当在代理实例上调用方法时,方法调用被编码并分配给其调用处理程序的invoke方法。
动态代理就是这样一种:
它是一个运行的生成类。当它生成时,你必须给它提供一组接口,然后类声明它实现这些接口。你可以使用这个类的实例作为这些接口中的任何一个。当然,这个动态代理其实就是一个代理,它不会为你做任何实质性的工作。当生成它的实例时,您必须提供一个处理程序,它将接管实际的工作。
当使用动态代理类时,我们必须实现InvocationHandler接口。
步骤:
1.定义抽象角色。
公共接口主题{
公共void请求();
}2.定义真正的角色
公共类RealSubject实现Subject {
@覆盖
公共无效请求(){
//TODO自动生成的方法存根
system . out . println( real subject );
}
}3.定义代理角色。
公共类DynamicSubject实现InvocationHandler {
私有对象sub
公共动态主题(对象对象){
this.sub=obj
}
@覆盖
公共对象调用(对象代理、方法方法、对象[]参数)
可投掷的
//TODO自动生成的方法存根
system . out . println( Method: Method ,Args: Args);
method.invoke(sub,args);
返回null
}
}4.通过Proxy.newProxyInstance构建代理对象
real subject real sub=new real subject();
invocation handler handler=new dynamic subject(real sub);
班级?class type=handler . getclass();
Subject sub=(Subject)proxy . new proxy instance(class type . get class loader(),
realSub.getClass()。getInterfaces()、handler);
system . out . println(sub . getclass());5.通过调用代理对象的方法来调用真实角色的方法。
sub。请求();输出:
类$Proxy0是实现指定接口的新代理对象。
方法:public abstract void dynamic proxy . subject . request(),args:nullrealpsubject调用的real对象的方法。
更多java知识,请关注java基础课程专栏。以上是java反射机制的详细内容,更多请关注我们的其他相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。