2012-01-25 81 views
5

我是一名Java初學者。我學到的第一件事是可執行類的main()方法應該是public並且給出的原因是因爲此方法將由JVM調用,所以應該在類的外部可見,因此應該是公開的。在研究序列化的過程中,我發現在序列化和反序列化對象時,JVM可以調用writeObject()readObject()類的私有方法!如果它們是私有方法,那麼JVM如何調用它們?如果可以的話,爲什麼它不能調用main()方法?JVM和私有方法

在翻閱了一些java文檔後,我讀了這一行「JVM可以訪問對象的私有方法」。由於我們使用ObjectInputStream的一個實例調用readObject(),因此它可以被JVM訪問,而main()方法是一個靜態或類方法,並且調用時沒有實例化該類的任何對象應該是公共的,以便JVM可訪問!那有意義嗎 ?我不知道 。

+0

應該是公開的,但他們告訴你錯誤的原因。正確的原因是因爲它在Java語言參考中是這樣說的。 – Ingo

回答

2

嗯,一般我同意@Christian,但我有2個注意事項:

  1. 的main()函數可以也取得了私人。

  2. 如果您確實需要,您還可以調用私有方法/函數。

1 JVM無論如何都可以調用main()。使它公開可以使應用程序的另一個代碼也可以調用main()方法。通常情況下,沒有人會這樣做。爲什麼main()是公開的,主要原因是歷史性的,AFAIC。其他程序語言也有main()函數,並且它是公共的。

2如果您真的需要,可以使用Core Reflection API調用私有方法或訪問私有字段。它看起來是這樣的:

 import java.lang.reflect.Field; 
     class SimpleKeyPair { 
     private String privateKey = "Cafe Babe"; // private field 
     } 
     public class PrivateMemberAccessTest { 
     public static void main(String[] args) throws Exception { 
      SimpleKeyPair keyPair = new SimpleKeyPair(); 
      Class c = keyPair.getClass(); 
      // get the reflected object 
      Field field = c.getDeclaredField("privateKey"); 
      // set accessible true 
      field.setAccessible(true); 
      // prints "Cafe Babe" 
      System.out.println("Value of privateKey: " + field.get(keyPair)); 
      // modify the member varaible 
      field.set(keyPair, "Java Duke"); 
      // prints "Java Duke" 
      System.out.println("Value of privateKey: " + field.get(keyPair)); 
     } 
     } 

http://www.jguru.com/faq/view.jsp?EID=321191

又見這個偉大的答案https://stackoverflow.com/a/2489644/1137529

4

這是關於約定。 JVM可以調用每個方法 - 它是JVM,老闆。如果JVM不能調用它,則沒有人可以。想象一下,JVM是你的程序被執行的地方,它是你和你的字節碼之間的某種代理。

writeObject可能無法在課堂外使用。這是一個內部唯一的方法,只爲你。因此,JVM的製造商同意將其保密。如果它不是私有的,程序中的其他類可以調用它。

main()方法是一種可能被其他Java進程調用的方法。如果它是私人的,其他程序無法啓動您的程序。它與JVM沒有多大關係,除了可以說通常JVM允許你(!)只調用你的代碼的public(包,受保護)方法。