Pregunta

In Java, by leaving the access modifier as the default one (blank), the fields becomes accessible to only members in the same package. However, this is not preventing others from declaring their classes in the same package and then accessing the "default" fields from there.

Is there a way in Java to make fields C# equivalent to internal. That is, when I build my library (JAR file), there's no way others can access those fields from outside the JAR? Even when declaring their classes in the same package as my classes.

Here is my declaration in my library:

package com.my.package;
class MyRestrictedClass{
}



What I'm trying to prevent is the user of my library to do from their project with my jar added to their build path something like:

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

Solución

You can seal the package. That prevents people from adding classes to the classpath (though you still have to protect your jars).

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

Having sealed your jar, you can still compile a class which claims to be in the same package, but when you run it, it'll fail to run:

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)

Otros consejos

you might want to try other access modifiers such as "protected". However: if someone really wants to access your method, he/she could use reflections and override the modifier at runtime, making it available as they want. They could go even further and e.g. remove final-flag and so on. So it's not safe to assume that if you use proper modifiers no one will be able to access your classes.

I don't know right now, but perhaps there is an annotation, which could help the user of your library understand, that they should not use your classes (except for the public API you provide). Perhaps there is something similar to @depricated or something, but I haven't used this myself.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top