Reputation: 12714
Assume I have a singleton class in an external lib to my application. But still I can create instances of that particular class using reflection. Like this
Class clas = Class.forName(Private.class.getName());
for(Constructor c : clas.getDeclaredConstructors()){
c.setAccessible(true);
Private p = (Private) c.newInstance();
System.out.println(p);
}
How can I restrict this ? .
Thanks J
Upvotes: 6
Views: 1610
Reputation: 15313
You can do like this.
private static final Private INSTANCE = new Private();
private Private() {
if(INSTANCE !=null)
throw new IllegalStateException("Already instantiated");
}
public static Private getInstance() {
return INSTANCE;
}
Upvotes: 0
Reputation: 18560
AFAIK this is sort of metaprogramming and therefore requires check on different layer of abstraction. From Javadoc I suppose, you should use SecurityManager to enforce the behaviour you want: setAccessible(). Generally IMHO you should really know what you are doing when you are metaprogramming and changing access should really have good reasons to be done.
Upvotes: 0
Reputation: 346260
If you're talking about singletons in particular: that's one reason why the best way to implement them is via an enum:
public enum YourSingleton {
INSTANCE;
// methods go here
}
If you're talking about using setAccessible()
in general: If the code is written by someone you don't trust not to do underhanded tricks like that, you shouldn't run it anyway (or run it in a sandbox). Among developers, public/private should be considered metainformation about how the code is intended to be used - not as a security feature.
Upvotes: 1
Reputation: 2055
See Hack any Java class using reflection attack and How to set SecurityManager and Java security policy programmatically .
Upvotes: 1
Reputation: 32831
By using a SecurityManager and controlling controlling ReflectPermission("suppressAccessChecks")
(example).
The security manager impacts performances though, and it is rarely used on the server side.
Upvotes: 6
Reputation: 2477
I don't think that you can restrict this.
It is obviously a dangerous/questionable practice to use reflection to access the private parts of others (snicker), but it is sometimes necessary by various types of tools and applications.
Upvotes: 0
Reputation: 165202
Long story short: you can't.
Any constructor, public as well as private, can be accessed by reflection and can be used to instantiate a new object.
You will need to resort to other methods such as SecurityManager
.
Upvotes: 0