Dosen't Reflection API打破了数据封装的目的吗? [英] Dosen't Reflection API break the very purpose of Data encapsulation?

查看:153
本文介绍了Dosen't Reflection API打破了数据封装的目的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Very recently I came across the Reflection API and to my surprise we can access and even alter the private variables.I tried the following code

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改变了目的数据封装?为什么我们必须使用Reflection API?我在一些网站上读到它可以用于测试目的,但据我说,模块已经过测试,可以使用JUnit测试用例轻松完成。所以有人可以解释为什么我们有这样的黑客?

We say Java is an Object oriented language and it's main features are Data Encapsulation, Inheritance, Polymorphism.. etc. Isn't the reflection API changing the very purpose of Data Encapsulation? Why do we have to use Reflection API? 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?

推荐答案


不是反射API改变数据封装的目的?

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

是和否。


  • 是的,反射API的一些用法可以打破数据封装。

  • 不,不是所有反射API的使用 打破数据封装。实际上,一个明智的程序员只有在有充分理由这样做时才会通过反射API打破封装。

  • 不,反射API不会改变目的数据封装。数据封装的目的保持不变......即使有人故意破坏它。

  • Yes, some uses of the reflection API can break data encapsulation.
  • No, not all uses of the reflection API do break data encapsulation. Indeed, a wise programmer only breaks encapsulation via the reflection API when there is a good reason to do so.
  • No, reflection API does not change the purpose of data encapsulation. The purpose of data encapsulation remains the same ... even if it someone wilfully breaks it.

为什么我们必须使用Reflection API?

Why do we have to use Reflection API?

不要打破封装的很多反射用法;例如使用反射来找出类的超类型,它有什么注释,它有什么成员,调用可访问的方法和构造函数,读取和更新可访问的字段等等。

There are many uses of reflection that DO NOT break encapsulation; e.g. using reflection to find out what super types a class has, what annotations it has, what members it has, to invoke accessible methods and constructors, read and update accessible fields and so on.

并且有些情况可以接受(在不同程度上)使用封装破坏各种反射:

And there are situations where is is acceptable (to varying degrees) to use the encapsulation breaking varieties of reflection:


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

  • You might need to look inside an encapsulated type (e.g. access / modify private fields) as the simplest way (or only way) to implement certain unit tests.

某些形式的依赖注入(也称为IoC),序列化和持久性需要访问和/或更新私有字段。

Some forms of Dependency Injection (aka IoC), Serialization and Persistence entail accessing and/or updating private fields.

偶尔,您需要打破封装才能工作围绕某些类中无法修复的错误。

Very occasionally, you need to break encapsulation to work around a bug in some class that you cannot fix.


我在一些网站上读过它可以用于测试目的,但根据我的模块进行了测试,可以使用JUnit t轻松完成最好的情况。所以有人可以解释为什么我们有这样的黑客?

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?

这取决于你班级的设计。设计为可测试的类将是可测试的,无需访问私有状态,或者将公开该状态(例如 protected getter)以允许测试。如果类没有这样做,那么JUnit测试可能需要使用反射来查看抽象内部。

That depends on the design of your class. A class that is designed to be testable will either be testable without the need to access "private" state, or will expose that state (e.g. protected getters) to allow testing. If the class doesn't do this, then a JUnit test may need to use reflection to look inside the abstraction.

这是不可取的(IMO),但如果你正在为某人编写的类编写单元测试,并且您无法调整API以提高可测试性,那么您可能必须选择使用反射还是不进行测试。

This is not desirable (IMO), but if you are writing unit tests for a class that someone wrote, and you can't "tweak" the APIs to improve testability, then you may have to choose between using reflection or not testing at all.

最重要的是数据封装是我们努力实现的理想(在Java中),但有些情况下,务实的正确做法是打破它或忽略它。

The bottom line is that data encapsulation is an ideal that we strive to achieve (in Java), but there are situations where the pragmatically correct thing to do is to break it or ignore it.

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

Note that not all OO languages support strong data encapsulation like Java does. For example, Python and Javascript are both unarguably OO languages, yet both make it easy for one class to access and modify the state of objects of another class ... or even change the other classes behaviour. Strong data abstraction is not central to everyone's view of what Object-Oriented means.

这篇关于Dosen't Reflection API打破了数据封装的目的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆