2

I'm working with a domain, view and controllers. Each containing their own classes.

The domain contains a lot of classes that should not be instantiated in classes outside of the domain. I was under the impression the default access modifier was going to help me. Making my domain classes their constructors package visible.

Turns out any class can still use the constructors after importing the right package.class file.

How can I prevent this from happening?

Razib
  • 10,965
  • 11
  • 53
  • 80
xrdty
  • 886
  • 2
  • 10
  • 22
  • 1
    Are your classes declared as public? https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html _"A class may be declared with the modifier public, in which case that class is visible to all classes everywhere. If a class has no modifier (the default, also known as package-private), it is visible only within its own package"_ – Vahx Apr 04 '15 at 17:35
  • 1
    This may also be useful http://stackoverflow.com/questions/215497/in-java-whats-the-difference-between-public-default-protected-and-private – Vahx Apr 04 '15 at 17:37

2 Answers2

3

When you say 'Turns out any class can still use the constructors after importing the right package.class file.' I guess you are talking about Reflection. Reflection is a powerful concept allowing arbitrary instantiation of classes even if they only provide a private constructor. There is no way to prevent someone from using reflection to instantiate your classes. The class or constructor modifiers such as private or protected can be bypassed using reflection.

muued
  • 1,666
  • 13
  • 25
  • It does seem that declaring the class' access modifier as package visible solves my problem. Thanks for the input though! – xrdty Apr 04 '15 at 17:47
  • Using Class.forName("package.subpackage...className") you can still get the Class object for the package-private class. This way you can get the declared constructors, make them accessible and just call them giving you an instance of the desired class. – muued Apr 04 '15 at 17:57
1

If you want to control the instantiation of a class from outside of the class then you may create it's constructor private like -

class A{

   private A(){
      // do some thing
   } 

   public static getInstance(){

   }
}   

Now now instance of class A can be created form the outside of the class. But if the outer world realy need an instance of the class then they can use the static method getInstance(). This construction prevents the outer world to create an instance of the class using new keyword.

Hope it will Help.
Thanks.

Razib
  • 10,965
  • 11
  • 53
  • 80