- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
最近我遇到了 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?
是也不是。
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/
一、反射 1.定义 Java的反射(reflection)机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法(即使是私有的);对于任意一个对象,都能够调用它的任意方法和属性,那么,我
有没有办法从 JavaScript 对象内部获取所有方法(私有(private)、特权或公共(public))?这是示例对象: var Test = function() { // private m
我有一个抽象类“A”,类“B”和“C”扩展了 A。我想在运行时根据某些变量创建这些实例。如下所示: public abstract class A { public abstract int
假设我们在内存中有很多对象。每个都有一个不同的ID。如何迭代内存以找到与某些 id 进行比较的特定对象?为了通过 getattr 获取并使用它? 最佳答案 您应该维护这些对象的集合,因为它们是在类属性
假设我有这个结构和一个方法: package main import ( "fmt" "reflect" ) type MyStruct struct { } func (a *MyS
C#反射简介 反射(Reflection)是C#语言中一种非常有用的机制,它可以在运行时动态获取对象的类型信息并且进行相应的操作。 反射是一种在.NET Framework中广
概述 反射(Reflection)机制是指在运行时动态地获取类的信息以及操作类的成员(字段、方法、构造函数等)的能力。通过反射,我们可以在编译时期未知具体类型的情况下,通过运行时的动态
先来看一段魔法吧 public class Test { private static void changeStrValue(String str, char[] value) {
结构体struct struct 用来自定义复杂数据结构,可以包含多个字段(属性),可以嵌套; go中的struct类型理解为类,可以定义方法,和函数定义有些许区别; struct类型是值类型
反射 1. 反射的定义 Java的反射(reflection)机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,既然能拿到那么,我们
反射的定义 java的反射(reflection) 机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,既然能拿到嘛,那么,我们就可以
我有一个 Java POJO: public class Event { private String id; private String name; private Lon
我编写了以下函数来检查给定的单例类是否实现了特征。 /** Given a singleton class, returns singleton object if cls implements T.
我正在研究 Java 反射的基础知识并观察有关类方法的信息。我需要获得一个符合 getMethod() 函数描述的规范的方法。然而,当我这样做时,我得到了一个 NoSuchMethodExceptio
我正在通过以下代码检索 IEnumerable 属性列表: BindingFlags bindingFlag = BindingFlags.Instance | BindingFlags.Public
我需要检查属性是否在其伙伴类中定义了特定属性: [MetadataType(typeof(Metadata))] public sealed partial class Address { p
我正在尝试使用 Reflections(由 org.reflections 提供)来处理一些繁重的工作,因此我不需要在很长的时间内为每个类手动创建一个实例列表。但是,Reflections 并未按照我
scala 反射 API (2.10) 是否提供更简单的方法来搜索加载的类并将列表过滤到实现定义特征的特定类? IE; trait Widget { def turn(): Int } class
我想在运行时使用反射来查找具有给定注释的所有类,但是我不知道如何在 Scala 中这样做。然后我想获取注释的值并动态实例化每个映射到关联注释值的带注释类的实例。 这是我想要做的: package pr
这超出了我的头脑,有人可以更好地向我解释吗? http://mathworld.wolfram.com/Reflection.html 我正在制作一个 2d 突破格斗游戏,所以我需要球能够在它击中墙壁
我是一名优秀的程序员,十分优秀!