首页 > 其他分享 >反射

反射

时间:2022-12-28 11:31:30浏览次数:31  
标签:反射 System class Person println Class out


反射:当一个字节码文件加载到内存的时候,JVM会对该字节码进行解剖,然后创建一个对象的Class对象,把字节码文件的信息全部都存储到该Class对象中,我们只要获取到Class对象,我们就可以使用字节码对象创建对象、设置对象的属性或者调用对象的方法等操作。



Java提供了三种方式获取类的字节码:


     forName("包名.类名")   forName方法用于加载某个类的字节码到内存中,并使用class对象进行封装。


    类名.class


    对象.getClass()



注意:在反射技术中,一个类的任何成员都有对应的类进行描述。例如:成员变量(Field类) 方法(Method类) 

package com.cn.reflect;
public class Person {
private int id;
String name;
public Person(int id, String name) {
this.id = id;
this.name = name;
}
private Person() {
}

public void eat(){
System.out.println(name + "高高兴兴吃饭。。。");
}

public void eat(int num){
System.out.println(name + "高高兴兴吃了" + num + "大碗饭。。。");
}

private void sleep(){
System.out.println(name + "偷偷睡觉。。。");
}

private static void work(){
System.out.println("努力工作。。。");
}

public void sum(int[] arr){
System.out.println("长度是" + arr.length);
}

@Override
public String toString() {
return "编号" + this.id + "\t姓名:" + this.name;
}
}


3种方式获取Class对象:

package com.cn.reflect;
/**
* Author:Liu Zhiyong
* Version:Version_1
* Date:2016年8月26日21:59:48
* Desc:
反射:当一个字节码文件加载到内存的时候,JVM会对该字节码进行解剖,然后创建一个对象的Class对象,把字节码文件的信息全部都存储到该Class对象中,我们只要获取到Class对象,我们就可以使用字节码对象设置对象的属性或者调用对象的方法等操作。
Java提供了三种方式获取类的字节码:
forName("包名.类名") forName方法用于加载某个类的字节码到内存中,并使用class对象进行封装。
类名.class
对象.getClass()
注意:在反射技术中,一个类的任何成员都有对应的类进行描述。例如:成员变量(Field类) 方法(Method类)
*/
public class Demo1 {

Person p;

public static void main(String[] args) throws ClassNotFoundException {
// Person p = new Person(110, "木丁西");

//推荐使用:获取Class对象的方式1:
Class c1 = Class.forName("com.cn.reflect.Person");
System.out.println(c1);

//获取Class对象的方式2:通过类名获取
Class c2 = Person.class;
System.out.println(c2);

//获取Class对象的方式3:通过对象获取
// Class c3 = new Person().getClass();

// System.out.println("c1 == c2 == c3 吗?" + (c1==c2 && c2==c3));
}
}


通过Class对象获取构造方法:

package com.cn.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* Author:Liu Zhiyong
* Version:Version_1
* Date:2016年8月26日22:27:30
* Desc:
如何通过Class对象获取构造方法。
*/
public class Demo2 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//获取到对应的Class对象
Class c1 = Class.forName("com.cn.reflect.Person");
//通过Class对象获取对应的构造方法
Constructor[] constructors = c1.getConstructors(); //获取此类所有公共的构造方法
for(Constructor c : constructors){
System.out.println(c);
}

Constructor[] constructors2 = c1.getDeclaredConstructors(); //获取此类的所有的构造方法,包括私有的在内
for(Constructor c : constructors2){
System.out.println(c);
}

Constructor<Person> c = c1.getConstructor(int.class, String.class);//获取单个的指定的构造方法
Person p = (Person)c.newInstance(120, "刘先森"); //newInstance() 创建一个对象

Constructor<Person> c2 = c1.getDeclaredConstructor();//获取单个的指定的构造方法
System.out.println(c2);
c2.setAccessible(true);//设置
Person p2 = c2.newInstance();
System.out.println(p2);
}
}


在反射技术中使用了Method类描述方法:

package com.cn.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Author:Liu Zhiyong
* Version:Version_1
* Date:2016年8月27日10:38:40
* Desc:
通过Class对象获取到对应的方法。
在反射技术中使用了Method类描述方法。
*/
public class Demo3 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
//获取对应 的Class对象
Class c = Class.forName("com.cn.reflect.Person");
//获取所有公共的方法
Method[] methods = c.getMethods();//getMethods()获取所有公共的方法,包括父类的
for(Method m : methods){
System.out.println(m);
}

System.out.println("==================================");

Method[] methods2 = c.getDeclaredMethods();//getDeclaredMethods()获取到所有的方法,但是不包含父类的方法
for(Method m : methods2){
System.out.println(m);
}
System.out.println("==================================");

Method method = c.getMethod("eat", null);
System.out.println(method);
System.out.println("==================================");

Method method2 = c.getMethod("eat", int.class);
System.out.println(method2);

System.out.println("==================================");

Constructor constructor = c.getConstructor(int.class, String.class);
Person p = (Person)constructor.newInstance(120, "小木");
method2.invoke(p, 3);//invoke() 第一个参数:方法的调用对象。 第二个参数:方法所需要的参数。
System.out.println("==================================");

//执行私有的方法
Method method3 = c.getDeclaredMethod("sleep", null);//获取私有方法
method3.setAccessible(true);//设置访问权限允许访问
method3.invoke(p, null);
System.out.println("==================================");

//执行静态的私有的方法
Method method4 = c.getDeclaredMethod("work", null);
method4.setAccessible(true);//设置访问权限允许访问
method4.invoke(null, null);//如果底层方法是静态的,那么可以忽略指定的 obj 参数。该参数可以为 null。
System.out.println("==================================");

//数组类型获取
Method method5 = c.getMethod("sum", int[].class);
method5.invoke(p, new int[]{1, 3, 5, 7, 9});
}
}


在反射技术中使用了Field类描述了成员变量:



package com.cn.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
/**
* Author:Liu Zhiyong
* Version:Version_1
* Date:2016年8月27日11:09:50
* Desc:
通过反射获取对应的成员变量
在反射技术中使用了Field类描述了成员变量。
*/
public class Demo4 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, NoSuchMethodException, InstantiationException, InvocationTargetException {
//获取到对应的Class对象
Class c = Class.forName("com.cn.reflect.Person");

//获取到所有的成员变量
Field[] fields = c.getDeclaredFields();
//fields = c.getFields();//获取所有的公共的成员变量,包括父类的
for(Field f : fields){
System.out.println(f);
}

System.out.println("=========================");

//获取一个对象
Constructor constructor = c.getConstructor(int.class, String.class);
Person p = (Person)constructor.newInstance(120, "木丁西");

//获取单个的成员变量
Field field = c.getDeclaredField("id");
//设置访问权限可以访问
field.setAccessible(true);
field.set(p, 155);//第一个参数:设置该数据的成员变量。第二个参数:属性值。
System.out.println(p);
}
}



标签:反射,System,class,Person,println,Class,out
From: https://blog.51cto.com/u_15769923/5974025

相关文章

  • 反射
    反射执行指定的方法publicvoidreflectTest()throwsException{Classclazz=Class.forName("com.jlpay.mng.agent.demo.AddAgent");Methodp......
  • 30_Java中的反射
    Java中的反射一、类加载器1、类加载:类加载的描述​ 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过类的加载,类的连接,类的初始化这三......
  • Go语言基础之反射
     变量的内在机制Go语言中的变量是分为两部分的:类型信息:预先定义好的元信息。值信息:程序运行过程中可动态变化的。反射介绍反射是指在程序运行期间对程序......
  • Java注解反射
    注解与反射内置注解@Oreride:定义在java.lang.Override中,此注释只适用于修辞方法,表示一个方法声明打算重写超类中的另一个方法声明。@Deprecated:定义在java.lang.Depr......
  • 注解与反射
    枚举反射基本数据类型注解packagecom.annotation_reflection.annotation;//注解importjava.util.ArrayList;importjava.util.List;publicclassTest01{......
  • Java反射详解,学以致用,实战案例(AOP修改参数、Mybatis拦截器实现自动填充)
    持续创作,加速成长!这是我参与「掘金日新计划·10月更文挑战」的第1天,点击查看活动详情作为Java开发者,你认为反射这个知识点重要程度,在你心里是什么样的呢?以前我也只觉......
  • 格路计数和反射容斥
    起源:将这个dp式子优化到线性。\[dp_{i,j}=\sum\limits_{k=j+1-b-a}^{j+1}{dp_{i-1,k}}\]考虑一个二维平面上,只能向右边或者上面走。也就是,当你走到\((......
  • 利用反射代替switch
    根据传进来不同的值,调用不同的方法ViewCodeprotectedvoidbtn_SwitchClick(objectsender,EventArgse){stringresult="";switch(ddlMethod.SelectedValue)......
  • 反射
    反射:框架设计的灵魂  *框架:半成品软件。可以在框架的基础上进行软件的开发,简化编码。  *反射:将类的各个组成部分封装为其他对象,这就是反射机制。   *好处:  ......
  • 重学c#系列—— 反射深入一点点[三十三]
    前言在上一章中介绍了什么是反射:https://www.cnblogs.com/aoximin/p/16440966.html正文上一节讲述反射的基本原理和为什么要用反射,还用反射的优缺点这些。其二者的......