SharedSecrets机制如何工作? [英] How does the SharedSecrets mechanism work?
问题描述
jdk.internal.misc.SharedSecrets
将自身描述为:
A 共享秘密的存储库,这是
在另一个包中调用实现 - 私有方法的机制,没有使用反射的
。 package-private类实现了一个公共
接口,并提供了在该包中调用package-private方法
的功能。实现该接口的对象是通过限制访问的第三个包提供的
。
这个框架避免了为此目的使用反射
的主要缺点,即丢失了编译时检查。
A repository of "shared secrets", which are a mechanism for calling implementation-private methods in another package without using reflection. A package-private class implements a public interface and provides the ability to call package-private methods within that package; the object implementing that interface is provided through a third package to which access is restricted. This framework avoids the primary disadvantage of using reflection for this purpose, namely the loss of compile-time checking.
有人可以提供一个示例来演示这种机制如何使一个包中的类能够访问另一个包中的包私有方法吗?
Can someone please provide an example that demonstrates how this mechanism enables classes in one package to access package-private methods in a different package?
推荐答案
引用 http://blog.fuseyism .com / index.php / 2008/05/26 / sharing-secrets / :
在浏览OpenJDK时VM项目,我注意到他们有一个相当有趣的解决方案。这封装在sun.misc.SharedSecrets中。此类提供对许多公共接口的实例的访问,例如sun.misc.JavaLangAccess。实际的实现在适当的包中作为内部类提供,例如java.lang,它可以访问私有变量和包私有变量和方法。
When looking through OpenJDK for the VM project, I noticed that they have a rather interesting solution to this. This is encapsulated in sun.misc.SharedSecrets. This class provides access to instances of a number of public interfaces, such as sun.misc.JavaLangAccess. The actual implementations are provided as inner classes in the appropriate package e.g. java.lang, where it has access to the private and package-private variables and methods within.
这是一个具体的例子:
- 我们有两个类:
字符
和故事
。 - 我们希望
Story
能够在字符上调用私有方法
但没有其他人。
- We have two classes:
Character
andStory
. - We want
Story
to be able to invoke private methods onCharacter
but no one else.
Main.java:
package external.main;
import external.character.Character;
import external.story.Story;
public class Main
{
public static void main(String[] args)
{
Story story = new Story();
story.introduce(Character.HARRY_POTTER);
story.introduce(Character.RON_WEASLEY);
story.introduce(Character.HERMIONE_GRANGER);
}
}
Story.java
package external.story;
import external.character.Character;
import internal.secrets.SharedSecrets;
public final class Story
{
/**
* Introduces a character.
*
* @param character the character
*/
public void introduce(Character character)
{
System.out.println(character.name() + " enters the room and says: " + SharedSecrets.INSTANCE.secretCharacter.getPhrase(character));
}
}
Character.java:
package external.character;
import internal.secrets.SecretCharacter;
import internal.secrets.SharedSecrets;
public enum Character
{
HARRY_POTTER
{
@Override
String getPhrase()
{
return "Your bird, there was nothing I could do. He just caught fire.";
}
},
RON_WEASLEY
{
@Override
String getPhrase()
{
return "Who are you and what have you done with Hermione Granger?";
}
},
HERMIONE_GRANGER
{
@Override
String getPhrase()
{
return "I'm not an owl!";
}
};
static
{
SharedSecrets.INSTANCE.secretCharacter = new SecretCharacter()
{
@Override
public String getPhrase(Character character)
{
return character.getPhrase();
}
};
}
/**
* @return the character's introductory phrase
*/
abstract String getPhrase();
}
SharedSecrets.java:
package internal.secrets;
public final class SharedSecrets
{
public static SharedSecrets INSTANCE = new SharedSecrets();
public SecretCharacter secretCharacter;
/**
* Prevent construction.
*/
private SharedSecrets()
{
}
}
SecretCharacter.java:
package internal.secrets;
import external.character.Character;
public interface SecretCharacter
{
/**
* @param character a character
* @return the character's introductory phrase
*/
String getPhrase(Character character);
}
module-info.java:
module SharedSecret
{
exports external.character;
exports external.main;
exports external.story;
}
输出
HARRY_POTTER进入房间说:你的鸟,我无能为力。他刚起火。
HARRY_POTTER enters the room and says: Your bird, there was nothing I could do. He just caught fire.
RON_WEASLEY进入房间说:你是谁,你和Hermione Granger做了什么?
RON_WEASLEY enters the room and says: Who are you and what have you done with Hermione Granger?
HERMIONE_GRANGER进入房间并说:我不是猫头鹰!
HERMIONE_GRANGER enters the room and says: I'm not an owl!
解释
-
external.character.Character.getPhrase()
受包保护。 -
external.story.Story
位于不同的包中。 - 通常
故事
将无法调用Character.getPhrase()
;但是,SharedSecrets
允许Character
与它信任的类共享访问权限。 -
Story
调用SharedSecrets.INSTANCE.secretCharacter
,它使用匿名嵌套类来访问Character
internals。 -
external.story.Story
可以访问internal.secrets.SharedSecrets
因为两者位于同一模块中,但外部用户无法访问它,因为module-info.java
不会导出该包。
external.character.Character.getPhrase()
is package-protected.external.story.Story
is located in a different package.- Normally
Story
wouldn't be able to invokeCharacter.getPhrase()
; however,SharedSecrets
allowsCharacter
to share access with classes that it trusts. Story
invokesSharedSecrets.INSTANCE.secretCharacter
which uses an anonymous nested class to accessCharacter
internals.external.story.Story
can accessinternal.secrets.SharedSecrets
because the two are located in the same module, but external users cannot access it becausemodule-info.java
does not export that package.
这篇关于SharedSecrets机制如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!