SharedSecrets机制如何工作? [英] How does the SharedSecrets mechanism work?

查看:1573
本文介绍了SharedSecrets机制如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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 and Story.
  • We want Story to be able to invoke private methods on Character 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 invoke Character.getPhrase(); however, SharedSecrets allows Character to share access with classes that it trusts.
  • Story invokes SharedSecrets.INSTANCE.secretCharacter which uses an anonymous nested class to access Character internals.
  • external.story.Story can access internal.secrets.SharedSecrets because the two are located in the same module, but external users cannot access it because module-info.java does not export that package.

这篇关于SharedSecrets机制如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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