gpt4 book ai didi

java - 反射 API 不会破坏数据封装的目的吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:41:59 25 4
gpt4 key购买 nike

最近我遇到了 Reflection API,令我惊讶的是我们可以访问甚至更改私有(private)变量。我尝试了以下代码

import java.lang.reflect.Field;

public class SomeClass{
private String name = "John";
}

public class Test{
public static void main(String args[]) throws Exception {
SomeClass myClass = new SomeClass();

Field fs = myClass.getClass().getDeclaredField("name");
fs.setAccessible(true);

System.out.println("Variable is " + fs.getName() + " and value is "
+ fs.get(myClass));

fs.set(myClass, "Sam");
System.out.println("Variable is " + fs.getName() + " and value is "
+ fs.get(myClass));
}
}

我得到了以下输出。

Variable is name and value is John
Variable is name and value is Sam

我们说 Java 是一种面向对象的语言,它的主要特性是数据封装、继承、多态性等。难道反射 API 不会改变数据封装的目的吗?为什么我们必须使用反射 API?我在一些网站上读到它可以用于测试目的,但根据我的说法,模块已经过测试,可以使用 JUnit 测试用例轻松完成。那么谁能解释为什么我们有这样的 hack?

最佳答案

Isn't the reflection API changing the very purpose of Data Encapsulation?

是也不是。

  • 是的,反射 API 的某些使用可以破坏数据封装。
  • 不,并非所有反射 API 的使用都会破坏数据封装。事实上,聪明的程序员只会在有充分理由的情况下通过反射 API 打破封装。
  • 不,反射 API 不会改变数据封装的目的。数据封装的目的保持不变......即使有人故意破坏它。

Why do we have to use Reflection API?

反射的许多用途不要破坏封装;例如使用反射找出一个类有哪些父类(super class)型、它有哪些注释、它有哪些成员、调用可访问的方法和构造函数、读取和更新可访问的字段等等。

在某些情况下,可以(在不同程度上)使用打破封装的各种反射:

  • 您可能需要查看封装类型内部(例如访问/修改私有(private)字段)作为实现某些单元测试的最简单方法(或唯一方法)。

  • 某些形式的依赖注入(inject)(又名 IoC)、序列化和持久化需要访问和/或更新私有(private)字段。

  • 偶尔,您需要打破封装以解决某些您无法修复的类中的错误。

I read in some sites that it can be used for testing purpose but according to me modules are tested and that can be done easily using JUnit test cases. So can anyone explain why do we have such a hack?

这取决于您的类(class)设计。设计为可测试的类要么无需访问“私有(private)”状态即可测试,要么公开该状态(例如 protected getter)以允许测试。如果类不执行此操作,则 JUnit 测试可能需要使用反射来查看抽象内部。

这是不可取的(IMO),但是如果您正在为某人编写的类编写单元测试,并且您不能“调整”API 以提高可测试性,那么您可能不得不在使用反射之间做出选择完全测试。


归根结底,数据封装是我们努力实现的理想(在 Java 中),但在某些情况下,实用的正确做法是破坏它或忽略它。

请注意,并非所有 OO 语言都像 Java 那样支持强大的数据封装。例如,Python 和 Javascript 无疑都是面向对象的语言,但它们都使一个类可以轻松访问和修改另一个类的对象的状态……甚至可以更改其他类的行为。强大的数据抽象并不是每个人对面向对象含义的看法的核心。

关于java - 反射 API 不会破坏数据封装的目的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16635025/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com