Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why am I able to have a public member in a non-public class?

Tags:

class MyClass  {     public static final int num=90; } 
  • Why am I allowed to create a public member in a non-public class?
  • Is there another way of accessing this member that I do not know of (other than through the class name)?
like image 210
XForCE07 Avatar asked Mar 03 '14 00:03

XForCE07


People also ask

Can we have a class without public?

classes when declared without any specified keyword is recognised as package-private, means the class can only be used inside the package.

Can a private class have public members Java?

Yes it is possible.

What is the difference between a public and a non public class?

A public class will have access specifier "public" and its members can be accessed with in and out of the class in which they are specified. A class which doesnt have the public access specifier are called as non-public classes and its member can be accessed only within the class in which they are specified.

Why do we use public for one class?

In any Java file, why can we have only one public class whose name is same as the Java file name? Because he said so!! To allow the compiler found easily the class definition. Its easier to compile that way.


2 Answers

Since your question was about members, I will address both fields and methods (non-static; Anthony Accioly's answer touches on another good use case, which also includes static fields).

While in many situations this is just an ambiguous consequence of the language's grammar (in particular: public fields in non-public classes, as in your example snippet), there are very good reasons for needing to be able to use public methods in non-public classes.

Expanding on Mik378's answer, consider, e.g., the following (contrived example):

import ...;  class BleebleAscendingComparator implements Comparator<Bleeble> {     @Override public int compare (Bleeble o1, Bleeble o2) { ... } }  class BleebleDescendingComparator implements Comparator<Bleeble> {     @Override public int compare (Bleeble o1, Bleeble o2) { ... } }  public class BleebleView {       public enum SortMode { ASC, DESC };     public Comparator<Bleeble> getDisplayOrderComparator (SortMode mode) {         if (mode == SortMode.ASC)             return new BleebleAscendingComparator();         else             return new BleebleDescendingComparator();     } } 

You cannot instantiate one of those Comparator implementations directly outside of that context, but they must override public methods of Comparator, and their functionality is accessible via a Comparator interface.

This same reasoning applies to, e.g., private or protected inner classes. If you were not able to declare methods public, you would have no way of overriding public methods of interfaces that they inherit or classes that they extends.

Practical Examples:

  • You use this every time you override a public method in an anonymous inner class (e.g. every time you override public void actionPerformed in an anonymous ActionListener).

  • Consider any non-public class that you would like to store in a HashMap. You would override the public equals() and hashCode() in that non-public class, and the implementation of HashMap can access them regardless of the fact that the class is non-public.

  • The often overridden public toString() is another common example of a public member of a potentially non-public class.

  • A more complex example is the use of java.sql.Driver in java.sql.DriverManager (in general, factory-type designs make heavy use of this concept) -- an SQL driver implementation may not make implementation classes public (e.g. the Oracle driver produces non-public Connection objects).

  • Many more... if you keep an eye out for examples of this, you'll be surprised how common it really is!

like image 122
Jason C Avatar answered Sep 22 '22 15:09

Jason C


Don't forget that classes with default access can be subclassed by public classes in the same package.

package package1;  class MyDefaultClass {      public static final int MY_CONSTANT = 0xCAFEBABE; }  public class PublicExporter extends MyDefaultClass {  } 

Now the public class acts as a bridge, and you are able to consume MyDefaultClass public members from other packages.

package package2;  import package1.PublicExporter;  public class Consumer {     public static void main(String[] args) {         System.out.printf("%x\n", PublicExporter.MY_CONSTANT);     } } 

Consumers can even import static members:

import static package1.PublicExporter.MY_CONSTANT;  public class Consumer {     public static void main(String[] args) {         System.out.printf("%x\n", MY_CONSTANT);     } } 
like image 24
Anthony Accioly Avatar answered Sep 19 '22 15:09

Anthony Accioly