java反射可以修改方法吗_Java反射

Java反射

允许程序在运行时来进行自我检查并且对内部的成员进行操作

反射主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能更具自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。

发射机制的作用:

1 在运行是判断任意一个对象所属的类

2 在运行时获取类的对象

3 在运行时访问Java对象的属性,方法,构造方法等。

反射依赖的主要类

1 Class

2 java.lang.reflect类库的主要类

a Filed :表示类中的成员变量

b:Method:表示类中的方法

c:Constructor:表示类的构造方法

d:Array:该类提供类动态创建数组和访问数组元素的静态方法

Class:

用来表示运行时类型信息的对应类

1 每个类都有一个唯一对应的Class对象。

2 Class类为类类型,而class对象为类类型对象

Class的特点:

1 Class类也是类的一种,class则时关键字

2 Class类只有一个私有构造函数,只有JVM能够创建Class的实例。

/*

* Private constructor. Only the Java Virtual Machine creates Class objects.

* This constructor is not used and prevents the default constructor being

* generated.

*/

private Class(ClassLoader loader) {

// Initialize final field for classLoader. The initialization value of non-null

// prevents future JIT optimizations from assuming this final field is null.

classLoader = loader;

}

3 JVM中只有唯一一个和类(相同包,类名,加载器)相对应的Class对象描述其类型信息

获取Class对象的三种方式:

1 Object geClass

2 类的.class属性

3 通过Class类的静态方法获取,forName();

如下:

public class ReflectTarget {

public static void main(String args[]) throws ClassNotFoundException {

//第一种方法

ReflectTarget target = new ReflectTarget();

Class reflectTargetClass1 = target.getClass();

System.out.println("1st:" + reflectTargetClass1.getName());

//第二种方式

Class reflectTargetClass2 = ReflectTarget.class;

System.out.println("2nd:" + reflectTargetClass2.getName());

System.out.println(reflectTargetClass1 == reflectTargetClass2);

//第三种方式

Class reflectTargetClass3 = Class.forName("com.yuns.demo.reflect.ReflectTarget");

System.out.println("3rd:" + reflectTargetClass3.getName());

System.out.println(reflectTargetClass2 == reflectTargetClass3);

}

}

在运行期间一个类只有一个Class对象产生

以上三种方式最后一种最常用,第一种有实例了还获取Class没有意义,第二种方式需要导入这个类,第三种只需要有类的包名和类名就可以了。

反射的主要用法:

如何获取类的构造方法并使用

如何获取类的成员变量并使用

如何获取类的成员方法并使用

构造函数获取并调用

由于反射可以获取到私有的构造函数,所以单例

public class ReflectTarget {

// 构造函数------------------

//默认带参数构造函数

ReflectTarget(String str) {

System.out.println("调用默认的构造方法参数:str=" + str);

}

//无参数构造函数

public ReflectTarget() {

System.out.println("调用公有的无参构造函数");

}

//有一个参数的构造函数

public ReflectTarget(char name) {

System.out.println("调用了带有一个参数的构造函数参数:name=" + name);

}

//有多个参数的构造函数

public ReflectTarget(String name, int index) {

System.out.println("调用了带有一个参数的构造函数参数:name=" + name + "index=" + index);

}

//受保护造函数

protected ReflectTarget(boolean b) {

System.out.println("调用受保护造函数");

}

//私有无参构造函数

private ReflectTarget(int index) {

System.out.println("私有的构造方法index:" + index);

}

//---------------字段-----------

public String name;

protected int index;

char type;

private String targetInfo;

//成员方法

public void show1(String s) {

System.out.println("调用公有的参数为String de show1");

}

protected void shows2() {

System.out.println("调用无参数受保护 show2 ");

}

void show3() {

System.out.println("调用无参数默认 show3 ");

}

private void show4(int index) {

System.out.println("调用私有有参数 show4 ");

}

@Override

public String toString() {

return "ReflectTarget[" +

"name='" + name + '\'' +

", index=" + index +

", type=" + type +

", targetInfo='" + targetInfo + '\'' +

']';

}

public static void main(String args[]) throws ClassNotFoundException {

//第一种方法

ReflectTarget target = new ReflectTarget();

Class reflectTargetClass1 = target.getClass();

System.out.println("1st:" + reflectTargetClass1.getName());

//第二种方式

Class reflectTargetClass2 = ReflectTarget.class;

System.out.println("2nd:" + reflectTargetClass2.getName());

System.out.println(reflectTargetClass1 == reflectTargetClass2);

//第三种方式

Class reflectTargetClass3 = Class.forName("com.yuns.demo.reflect.ReflectTarget");

System.out.println("3rd:" + reflectTargetClass3.getName());

System.out.println(reflectTargetClass2 == reflectTargetClass3);

}

}

public class ConstructorCollector {

public static void main(String args[]) throws Exception {

/**

*获取构造函数方法:

* 1)获取批量构造函数:

* public Constructor[] getConstructor():所有公有的构造函数

* public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有,受保护,公有的)

* 2)获取单个构造函数

* public Constructor getConstructor(Class... parameterTypes):获取单个的公有的构造函数

* public Constructor getDeclaredConstructor(Class... parametertype):获取单个公有,受保护,私有的构造函数

*

* 调用构造函数:

* Constructor-->newInstance(Object... initaggs)

*/

Class reflectTargetClass = Class.forName("com.yuns.demo.reflect.ReflectTarget");

System.out.println("-------获取所有公有的构造函数------");

Constructor[] allPublicConstructor = reflectTargetClass.getConstructors();

for (Constructor constructor : allPublicConstructor) {

System.out.println(constructor);

}

System.out.println("-------获取所有构造函数------");

Constructor[] allConstructor = reflectTargetClass.getDeclaredConstructors();

for (Constructor constructor : allConstructor) {

System.out.println(constructor);

}

System.out.println("--------获取公有的有两个参数的构造函数-----");

Constructor manyParamCon = reflectTargetClass.getConstructor(String.class,int.class);

System.out.println(manyParamCon);

ReflectTarget target = (ReflectTarget) manyParamCon.newInstance("test",1);

System.out.println("--------获取私有的构造函数-----");

Constructor privateParamCon = reflectTargetClass.getDeclaredConstructor(int.class);

//暴力访问私有构造函数

privateParamCon.setAccessible(true);

ReflectTarget privateTarget = (ReflectTarget) privateParamCon.newInstance(1);

System.out.println(privateParamCon);

}

}

输出:

-------获取所有公有的构造函数------

public com.yuns.demo.reflect.ReflectTarget(java.lang.String,int)

public com.yuns.demo.reflect.ReflectTarget()

public com.yuns.demo.reflect.ReflectTarget(char)

-------获取所有构造函数------

private com.yuns.demo.reflect.ReflectTarget(int)

protected com.yuns.demo.reflect.ReflectTarget(boolean)

public com.yuns.demo.reflect.ReflectTarget(java.lang.String,int)

com.yuns.demo.reflect.ReflectTarget(java.lang.String)

public com.yuns.demo.reflect.ReflectTarget()

public com.yuns.demo.reflect.ReflectTarget(char)

--------获取公有的有两个参数的构造函数-----

public com.yuns.demo.reflect.ReflectTarget(java.lang.String,int)

调用了带有一个参数的构造函数参数:name=testindex=1

--------获取私有的构造函数-----

私有的构造方法index:1

private com.yuns.demo.reflect.ReflectTarget(int)

Process finished with exit code 0

对象字段获取并设置值:

public class FieldCollector {

/**

* 获取成员变量

* 1)批量获取

* 1 Field[] getFields();获取所有的公有字段,及父类公有字段

* 2 Field[] getDeclaredFields():获取所欲字段(公有,私有,保护),不能访问父类变量

* 2)获取单个

* 1 public Field getField(String fieldName):获取某个公有字段及父类公有字段

* 2 public Field getDeclaredField(String fieldName):获取某个字段(公有,私有,保护),不能访问父类变量

* 设置字段的值:

* Field--> public void set(Object obj,Object value):

* 参数说明:obj要设置的字段所在的对象;

* value:要为字段设置的值;

*/

public static void main(String args[]) throws Exception {

Class reflectTargetClass = Class.forName("com.yuns.demo.reflect.ReflectTarget");

System.out.println("-------获取所有公有字段-----");

Field[] allPublicField = reflectTargetClass.getFields();

for (Field field : allPublicField) {

System.out.println(field);

}

System.out.println("-------获取所有字段-----");

Field[] allField = reflectTargetClass.getDeclaredFields();

for (Field field : allField) {

System.out.println(field);

}

System.out.println("获取单个特定公有的字段并赋值");

Field publicField = reflectTargetClass.getField("name");

System.out.println("获取到的公有字段" + publicField);

ReflectTarget target = (ReflectTarget) reflectTargetClass.getConstructor().newInstance();

publicField.set(target, "待反射一号");

//验证对应name

System.out.println("验证name " + target.name);

System.out.println("-------获取单个私有的Field------");

Field privateField = reflectTargetClass.getDeclaredField("targetInfo");

//暴力访问私有字段

privateField.setAccessible(true);

privateField.set(target, "908818818");

System.out.println(target);

}

}

-------获取所有公有字段-----

public java.lang.String com.yuns.demo.reflect.ReflectTarget.name

-------获取所有字段-----

public java.lang.String com.yuns.demo.reflect.ReflectTarget.name

protected int com.yuns.demo.reflect.ReflectTarget.index

char com.yuns.demo.reflect.ReflectTarget.type

private java.lang.String com.yuns.demo.reflect.ReflectTarget.targetInfo

获取单个特定公有的字段并赋值

获取到的公有字段public java.lang.String com.yuns.demo.reflect.ReflectTarget.name

调用公有的无参构造函数

验证name 待反射一号

-------获取单个私有的Field------

ReflectTarget[name='待反射一号', index=0, type=, targetInfo='908818818']

Process finished with exit code 0

方法获取并调用:

public class MethodCollector {

/**

* 1)批量获取的

* public Method[] getMethods():获取所有公有的方法和父类的公有方法

* public Method[] getDeclaredMethods():获取所有方法(公有,私有,保护)不能访问父类中的方法

* 2)获取单个的:

* public Method getMethod(String name,Class> parametertypes):

* 参数:

* name :方法名

* Class..:形参的Class类型对象

* public Method getDeclaredMethod(String name,Class> parametertypes)

*

*

* 调用方法:

* Method --> public Object invoke(Object obj,Object...args):

* 参数说明:

* obj:要调用方法对象;

* args:调用方法时传递的实参;

*/

public static void main(String args[]) throws Exception {

Class reflectTargetClass = Class.forName("com.yuns.demo.reflect.ReflectTarget");

System.out.println("-------获取所有公有方法---------");

Method[] allPublicMethod = reflectTargetClass.getMethods();

for (Method method : allPublicMethod) {

System.out.println(method);

}

System.out.println("-------获取所有方法---------");

Method[] allMethod = reflectTargetClass.getDeclaredMethods();

for (Method method : allMethod) {

System.out.println(method);

}

Method publicMethod = reflectTargetClass.getMethod("show1", String.class);

System.out.println("---获取到的具体的公有方法---" + publicMethod);

ReflectTarget target = (ReflectTarget) reflectTargetClass.getConstructor().newInstance();

publicMethod.invoke(target, "待调用公有方法");

Method privateMethod = reflectTargetClass.getDeclaredMethod("show4", int.class);

System.out.println("---获取到的具体的私有方法---" + privateMethod);

privateMethod.setAccessible(true);

privateMethod.invoke(target, -1000);

}

}

结果:

-------获取所有公有方法---------

public static void com.yuns.demo.reflect.ReflectTarget.main(java.lang.String[]) throws java.lang.ClassNotFoundException

public java.lang.String com.yuns.demo.reflect.ReflectTarget.toString()

public void com.yuns.demo.reflect.ReflectTarget.show1(java.lang.String)

public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException

public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException

public final void java.lang.Object.wait() throws java.lang.InterruptedException

public boolean java.lang.Object.equals(java.lang.Object)

public native int java.lang.Object.hashCode()

public final native java.lang.Class java.lang.Object.getClass()

public final native void java.lang.Object.notify()

public final native void java.lang.Object.notifyAll()

-------获取所有方法---------

public static void com.yuns.demo.reflect.ReflectTarget.main(java.lang.String[]) throws java.lang.ClassNotFoundException

public java.lang.String com.yuns.demo.reflect.ReflectTarget.toString()

void com.yuns.demo.reflect.ReflectTarget.show3()

protected void com.yuns.demo.reflect.ReflectTarget.shows2()

private void com.yuns.demo.reflect.ReflectTarget.show4(int)

public void com.yuns.demo.reflect.ReflectTarget.show1(java.lang.String)

---获取到的具体的公有方法---public void com.yuns.demo.reflect.ReflectTarget.show1(java.lang.String)

调用公有的无参构造函数

调用公有的参数为String de show1

---获取到的具体的私有方法---private void com.yuns.demo.reflect.ReflectTarget.show4(int)

调用私有有参数 show4

Process finished with exit code 0

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值