java反射深入_【Reflect】深入理解Java反射

本文详细介绍了Java反射机制的三种实现方式,包括通过对象的getClass()、类的.class属性以及Class.forName()方法获取类的字节码文件。接着,展示了如何通过反射获取类的构造方法、属性和方法,并提供了相关示例。最后,讨论了反射的优缺点,如增加程序灵活性但降低执行效率,以及可能暴露私有信息。
摘要由CSDN通过智能技术生成

反射的概述:java的反射机制是在程序的运行过程中,对于任何一个类,能够知道它的有哪些属性和方法;对于任何一个对象,都能对它的方法和属性进行调用;将这种动态获取对象信息以及调用对象方法的功能称为j反射机制。

java反射机制类java.lang.Class; //类

java.lang.reflect.Constructor;//构造方法

java.lang.reflect.Field; //类的成员变量(字段)

java.lang.reflect.Method;//类的方法

java.lang.reflect.Modifier;//访问权限

一.反射的三种方式(获取类的字节码文件,也就是.class文件):

1.Object中的getClass()

a17d451e9557f9bb171b60d6b0b4dd12.png

public static void main(String[] args) {

Demo demo = new Demo();

//获取该类的全路径名称

String name = demo.getClass().getName();

}

2.类.classpublic static void main(String[] args) {

Class c = Demo.class;

//获取该类的全路径名称

c.getName();

}

3.通过拿到类的全路径名来获取该类的字节码文件(如果找不到该路径下的此类,会抛出以下异常)public static void main(String[] args) {

try {

Class> c = Class.forName("interview_questions.Demo");

c.getName();

}catch (ClassNotFoundException cnfe){

cnfe.printStackTrace();

}

}

以上是获取一个类的字节码文件的三种方式,但是选择哪种好呢?第一种:我们获取字节码文件是为了调用该类的方法和属性,既然已经拿到了它的实例,就不需要字节码文件了;

第二种:通过这种方式去拿到它的字节码文件,就必须先要将该类的包导入,这种依赖性很强;

第三种:直接拿到该类的全路径名,通过全路径名的方式加载得到它的字节码文件。(常用)

二.通过反射获取类的构造方法、属性和类中方法//user类

public class user {

public String name;

public Integer age;

private String address;

public user(){

super();

}

public user(String name, Integer age, String address) {

this.name = name;

this.age = age;

this.address = address;

}

private user(String name, String address) {

this.name = name;

this.address = address;

}

public void test01(String name,Integer age){

System.out.println("user类中的test01方法(public)_"+name+"_"+age);

}

private void test02(){

System.out.println("user类中的test02方法(private)");

}

protected void test03(){

System.out.println("user类中的test03方法(protected)");

}

void test04(){

System.out.println("user类中的test04方法");

}

}

1.获取类的构造方法public static void main(String[] args) throws Exception{

Class> user = Class.forName("interview_questions.user");

//public constructor

Constructor>[] constructors = user.getConstructors();

//All constructor

Constructor>[] cons = user.getDeclaredConstructors();

//public constructor no param

Constructor> constructor = user.getDeclaredConstructor(null);

//public constructor and param

Constructor> constructor1 = user.getConstructor(new Class[]{String.class,Integer.class, String.class});

//private constructor and param

Constructor> constructor2 = user.getDeclaredConstructor(new Class[]{String.class, String.class});

}

}

打印输出---------------public constructor--------------------

public interview_questions.user()

public interview_questions.user(java.lang.String,java.lang.Integer,java.lang.String)

---------------All constructor---------------------

public interview_questions.user()

public interview_questions.user(java.lang.String,java.lang.Integer,java.lang.String)

private interview_questions.user(java.lang.String,java.lang.String)

--------------public constructor no param-----------

public interview_questions.user()

--------------public constructor and param----------

public interview_questions.user(java.lang.String,java.lang.Integer,java.lang.String)

--------------private constructor and param--------

private interview_questions.user(java.lang.String,java.lang.String)

2.获取类属性//获取public修饰的所有字段

Field[] fields = user.getFields();

//获取类中所有字段

Field[] declaredFields = user.getDeclaredFields();

//获取指定的public字段,并设置值

Field name = user.getField("name");

//获取实例对象

Object obj = user.getConstructor().newInstance();

name.set(obj,"xiaoming");

user u = (user)obj;

System.out.println(u.name);//xiaoming

//获取类中的私有字段,并设置值

对于私有字段,设置Field对象的Accessible的访问标志位为Ture,就可以通过反射获取私有变量的值,在访问时会忽略访问修饰符的检查Field address = user.getDeclaredField("address");

Object obj01 = user.getConstructor().newInstance();

address.setAccessible(true);

address.set(obj01,"beijing");

String s = (String) address.get(obj01);

3.获取类中的方法先在user类中添加四个方法:

public void test01(String name,Integer age){

System.out.println("user类中的test01方法(public)_"+name+"_"+age);

}

private void test02(){

System.out.println("user类中的test02方法(private)");

}

protected void test03(){

System.out.println("user类中的test03方法(protected)");

}

void test04(){

System.out.println("user类中的test04方法");

}

//获取所有public修饰的方法

Method[] methods = user.getMethods();

//获取user类中所有的方法

Method[] declaredMethods = user.getDeclaredMethods();

//获取指定方法并调用执行

Method test01 = user.getMethod("test01", String.class,Integer.class);

Object obj = user.getConstructor().newInstance();

Object invoke = test01.invoke(obj, "xiaoming",18);

System.out.println(invoke);

反射的优缺点:优点:增加程序的灵活性、外部调用方便

缺点:性能比起源代码执行效率低;内部暴露(比如一些在正常情况下不允许访问的私有属性和方法)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值