java反射 优缺点_java反射

本文详细介绍了Java反射的概念,通过实例展示了如何使用反射进行动态实例化、访问私有属性和方法。同时,讨论了反射的优缺点,如增加程序灵活性、降低性能以及安全性问题。文中还提到了Spring框架中的反射应用,如IOC和DI。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java反射

什么是反射?

一种动态实例化对象,并且可以获取到实例对象的属性,方法,并对其进行一些操作

常规调用对象

在 Java 中创建对象,获取属性,调用对象的方法通常都是通过 Object o = new Object(), 然后通过 o.getXXX(), o.setXXX() o.doSomething()来实现。

反射调用对象

Class> classBook = Class.forName("com.android.peter.reflectdemo.Book");

Object objectBook = classBook.newInstance();

Book book = (Book) objectBook;

反射的例子

底层组件,调用上层业务对象

spring

反射的优缺点

优点

增加程序的灵活性,避免将固有逻辑写死

代码简洁,可读性强,可提高代码的复用率

缺点

相比较于直接调用,在访问量较大的情况下,反射会导致系统性能明显下降

打破了类的封装性,存在一定的安全隐患

为什么反射慢?

反射调用会进行一系列的安全性校验

反射需要调用一系列的native方法来实现

寻找Class字节码的过程,比如通过ClassName找到对应的字节码Class,然后进行加载、解析,也会比较慢,而new的方式则无需寻找,因为在Linking的解析阶段已经将符号引用转为了直接引用

入参校验

反射代码例子

被反射类Book.java

public class Book{

private final static String TAG = "BookTag";

private String name;

private String author;

@Override

public String toString() {

return "Book{" +

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

", author='" + author + '\'' +

'}';

}

public Book() {

}

private Book(String name, String author) {

this.name = name;

this.author = author;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getAuthor() {

return author;

}

public void setAuthor(String author) {

this.author = author;

}

private String declaredMethod(int index) {

String string = null;

switch (index) {

case 0:

string = "I am declaredMethod 1 !";

break;

case 1:

string = "I am declaredMethod 2 !";

break;

default:

string = "I am declaredMethod 1 !";

}

return string;

}

}

创建对象

try {

Class> classBook = Class.forName("com.android.peter.reflectdemo.Book");

Object objectBook = classBook.newInstance();

Book book = (Book) objectBook;

book.setName("Android进阶之光");

book.setAuthor("刘望舒");

Log.d(TAG,"reflectNewInstance book = " + book.toString());

} catch (Exception ex) {

ex.printStackTrace();

}

反射私有的构造方法

try {

Class> classBook = Class.forName("com.android.peter.reflectdemo.Book");

Constructor> declaredConstructorBook = classBook.getDeclaredConstructor(String.class,String.class);

declaredConstructorBook.setAccessible(true);

Object objectBook = declaredConstructorBook.newInstance("Android开发艺术探索","任玉刚");

Book book = (Book) objectBook;

Log.d(TAG,"reflectPrivateConstructor book = " + book.toString());

} catch (Exception ex) {

ex.printStackTrace();

}

反射私有属性

try {

Class> classBook = Class.forName("com.android.peter.reflectdemo.Book");

Object objectBook = classBook.newInstance();

Field fieldTag = classBook.getDeclaredField("TAG");

fieldTag.setAccessible(true);

String tag = (String) fieldTag.get(objectBook);

Log.d(TAG,"reflectPrivateField tag = " + tag);

} catch (Exception ex) {

ex.printStackTrace();

}

反射私有方法

try {

Class> classBook = Class.forName("com.android.peter.reflectdemo.Book");

Method methodBook = classBook.getDeclaredMethod("declaredMethod",int.class);

methodBook.setAccessible(true);

Object objectBook = classBook.newInstance();

String string = (String) methodBook.invoke(objectBook,0);

Log.d(TAG,"reflectPrivateMethod string = " + string);

} catch (Exception ex) {

ex.printStackTrace();

}

获取成员变量并调用

1.批量的

1).Field[] getFields():获取所有的"公有字段"

2).Field[] getDeclaredFields():获取所有字段,包括:私有、受保护、默认、公有;

2.获取单个的:

1).public Field getField(String fieldName):获取某个"公有的"字段;

2).public Field getDeclaredField(String fieldName):获取某个字段(可以是私有的)

获取成员方法并调用

1.批量的:

public Method[] getMethods():获取所有"公有方法";(包含了父类的方法也包含Object类)

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:调用方式时所传递的实参;

Spring IOC 和 DI

也是利用的反射

IOC(Inversion of Control)

控制反转是一种设计思想,并非实际的技术,最核心的思想就是将预先设计的对象实例创建的控制权交给程序(IOC容器)。

注:IOC容器大家可以简单认为是一个KV的Map集合

DI(Dependency Injection)

依赖注入,对象的构建过程中,IOC容器动态提供这个对象所需要的其他对象.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值