2013-11-04 17 views
6

在Java中,通過將訪問修飾符保留爲默認值(空白),這些字段僅對同一包中的成員可訪問。但是,這並不妨礙其他人在相同的包中聲明他們的類,然後從那裏訪問「默認」字段。

有沒有一種方法可以讓Java字段C#相當於internal。也就是說,當我構建我的庫(JAR文件)時,其他人無法從JAR外部訪問這些字段?即使在與我的課程相同的包中聲明他們的課程時也是如此。

這是我在我的庫聲明:Java相當於C#的「內部」

package com.my.package; 
class MyRestrictedClass{ 
} 



我試圖阻止我的圖書館的用戶從他們的項目與我的罐子加入到他們的構建路徑例如:

package com.my.package; //Add their class to my package 
public class DeveloperClass{ 
    public void main(){ 
     MyRestrictedClass foo = new MyRestrictedClass(); 
    } 
} 

回答

7

您可以密封包裝。這可以防止人們將類添加到類路徑中(儘管您仍然需要保護您的罐子)。

http://docs.oracle.com/javase/tutorial/deployment/jar/sealman.html

具有密封的罐子你,你仍然可以編譯聲稱是在同一個包中的類,但是當你運行它,它會無法運行:

Exception in thread "main" java.lang.SecurityException: sealing violation: can't seal package org.splore.so.access: already loaded 
at java.net.URLClassLoader.getAndVerifyPackage(URLClassLoader.java:395) 
at java.net.URLClassLoader.defineClass(URLClassLoader.java:417) 
at java.net.URLClassLoader.access$100(URLClassLoader.java:71) 
at java.net.URLClassLoader$1.run(URLClassLoader.java:361) 
at java.net.URLClassLoader$1.run(URLClassLoader.java:355) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.net.URLClassLoader.findClass(URLClassLoader.java:354) 
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) 
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) 
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) 
at org.splore.so.access.AccessTestFromOtherPackage.main(AccessTestFromOtherPackage.java:5) 
+0

我試過了。但是我仍然可以從jar外部訪問我的「默認」類。我檢查了我的清單,它確實是密封的。 – AxiomaticNexus

+0

你確定你的「默認」類是正確定義的嗎? – CPerkins

+0

我想: 'class MyClass {}' 從一個將jar添加到其構建路徑的項目中,我仍然可以這樣做:'MyClass myClass = new MyClass();'。只有當我聲明調用代碼當然是在相同的包中。 – AxiomaticNexus

-1

您可能想嘗試其他訪問修飾符,例如「protected」。然而,如果有人真的想訪問你的方法,他/她可以在運行時使用反射並覆蓋修飾符,使其可以隨意使用。他們可以走得更遠,例如刪除最終標誌等。所以假設如果你使用適當的修飾符,沒有人能夠訪問你的類是不安全的。

我現在不知道,但也許有一個註釋,它可以幫助你的圖書館的用戶明白,他們不應該使用你的類(除了你提供的公共API)。也許有類似於@depricated或類似的東西,但我沒有用過這個。

+1

這將是很好,如果downvoters有耐心解釋他們爲什麼downvote ... – Igor

+1

是不是我,但我的猜測是downvote是因爲'受保護'實際上比(默認)更容易訪問,並且您的答案並不能真正解決問題,而只是一種猜測。 – AxiomaticNexus