2017-10-13 22 views
2

jdk.internal.misc.SharedSecrets自己描述为:SharedSecrets机制如何工作?

的“共享秘密”,这是使用反射为 调用另一个包实现的私有方法的机制,而不 信息库。包私有类实现公共接口 ,并提供在包中调用包私有方法 的能力;实现该接口的对象是通过访问受限的第三个包提供的 。 该框架避免了为此目的使用反射 的主要缺点,即编译时检查的损失。

有人可以请示例说明这种机制如何使一个包中的类可以访问不同包中的包 - 私有方法?

+1

由于此技术自从Java 1.1和Sun的'SharedSecrets'并不太年轻,因此与'[java-9]'没有关系。这可以用你在答案中引用的文章已近10年的事实来说明。 – Holger

+0

....以及JDK9中有关'SharedSecrets'的唯一相关变化,我可以找到[是这个](https://stackoverflow.com/questions/46612648/javalangaccess-and-sharedsecrets-in-java-9) – nullpointer

回答

0

报价http://blog.fuseyism.com/index.php/2008/05/26/sharing-secrets/

当通过OpenJDK的寻找VM项目,我发现他们有一个非常有趣的解决了这一点。这被封装在sun.misc.SharedSecrets中。该类提供对许多公共接口(如sun.misc.JavaLangAccess)的实例的访问。实际的实现在适当的包中作为内部类提供,例如java.lang,它可以在其中访问私有和包私有变量和方法。

下面是一个具体的例子:

SharedSecrets.java:

package internal.secrets; 

public final class SharedSecrets 
{ 
    public static SharedSecrets INSTANCE = new SharedSecrets(); 
    public SecretCharacters secretCharacters; 

    /** 
    * Prevent construction. 
    */ 
    private SharedSecrets() 
    { 
    } 
} 

SecretCharacters.java:

package internal.secrets; 

import external.character.Characters; 

public interface SecretCharacters 
{ 
    /** 
    * Execute a secret handshake with the character. 
    * 
    * @param character the character whose hand to shake 
    */ 
    void secretHandshake(Characters character); 
} 

Characters.java:

package external.character; 

import internal.secrets.SecretCharacters; 
import internal.secrets.SharedSecrets; 

public enum Characters 
{ 
    HARRY_POTTER 
    { 
     @Override 
     void secretHandshake() 
     { 
      System.out.println("Your bird, there was nothing I could do. He just caught fire."); 
     } 
    }, 
    RON_WEASLEY 
    { 
     @Override 
     void secretHandshake() 
     { 
      System.out.println("Who are you and what have you done with Hermione Granger?"); 
     } 
    }, 
    HERMIONE_GRANGER 
    { 
     @Override 
     void secretHandshake() 
     { 
      System.out.println("I'm not an owl!"); 
     } 
    }; 

    static 
    { 
     SharedSecrets.INSTANCE.secretCharacters = new SecretCharacters() 
     { 
      @Override 
      public void secretHandshake(Characters character) 
      { 
       character.secretHandshake(); 
      } 
     }; 
    } 

    /** 
    * Execute a secret handshake with the character. 
    */ 
    abstract void secretHandshake(); 
} 

Story.java:

package external.story; 

import external.character.Characters; 
import internal.secrets.SharedSecrets; 

public final class Story 
{ 
    /** 
    * Adds a character to the story. 
    * 
    * @param character a character 
    */ 
    public void add(Characters character) 
    { 
     SharedSecrets.INSTANCE.secretCharacters.secretHandshake(character); 
    } 
} 

Main.java:

package external.main; 

import external.character.Characters; 
import external.story.Story; 

public class Main 
{ 
    public static void main(String[] args) 
    { 
     Story story = new Story(); 
     story.add(Characters.HARRY_POTTER); 
     story.add(Characters.RON_WEASLEY); 
     story.add(Characters.HERMIONE_GRANGER); 
    } 
} 

module-info.java:

module SharedSecret 
{ 
    exports external.character; 
    exports external.main; 
    exports external.story; 
} 

输出

你的鸟,没有什么我可以做的。他只是着火了。

你是谁?你和赫敏格兰杰做了什么?

我不是猫头鹰!

说明

  • external.story.Story被调用external.character.Characters.secretHandshake()即使该方法包保护和位于一个单独的程序包。
  • 方法调用通过可通过SharedSecrets.INSTANCE.secretCharacters访问的匿名嵌套类。
  • external.story.Story可以访问internal.secrets.SharedSecrets,因为它位于同一个模块中,但外部用户不能这样做,因为module-info.java不会导出该程序包。