19

I was going through a part of a code which was something like this

// compare points according to their polar radius
public static final Comparator<Point2D> R_ORDER = new ROrder();
.
.
.
private static class ROrder implements Comparator<Point2D> {
    public int compare(Point2D p, Point2D q) {
        double delta = (p.x*p.x + p.y*p.y) - (q.x*q.x + q.y*q.y);
        if (delta < 0) return -1;
        if (delta > 0) return +1;
        return 0;
    }
}

Why do we have such public methods inside private static classes. What harm would it do if i made ROrder

  1. Non-Static
  2. Public
Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
Somjit
  • 2,503
  • 5
  • 33
  • 60
  • 2
    possible duplicate of [public methods in package-private classes](http://stackoverflow.com/questions/5260467/public-methods-in-package-private-classes) – Vignesh Vino Sep 18 '13 at 09:29

4 Answers4

11

ROrder Non-Static

By making it non-static you will need the instance of the container class to create the instance of ROder, which maybe due to the design of the class would not make logic. You should keep class non-static only when you really need the instance of outer class to get the instance of inner class.

ROrder Public

Again because they wanted to restrict the use of ROrder outside the context of this class. They did not want any client code or other code to freely create instances of ROrder, as they would not be of any use.

Why do we have such public methods inside private static classes.

In this case because you are implementing an interface Comparator and you will pass this comparator for other uses, such as sorting and you would want the Collections class to have the visibility of compare method, so the method has to be public even if the class implementing the interface is private.

So this is just a logical way to enhance the readability and intent of use of the code.

Logical Use

This class wants the string to be in some format.

public class SomeClass{

     private static class StringHelper{
          //will do the task of parsing and validating that string object
     } 
}

Now in this case you would not want to keep StringHelper class public, as its use is too localized to be reused. So you would rather emphasize that by keeping it private. And there can be methods that are public if StringHelper implemented some interface.

UPDATE:

You should keep class non-static only when you really need the instance of outer class to get the instance of inner class.

On that I think the answer can be too broad, but I would try to explain in short. By that what I mean was that if the inner class object shares some state of the outer object on which its processing is dependent, then you will need the object of outer class to share its state with the inner class object, but if the inner class instance is independent of the state of outer class, then it is safe to keep the inner class static.

Narendra Pathai
  • 41,187
  • 18
  • 82
  • 120
  • Thanks a lot for looking into and providing answers to the two questions i asked as well as explaining the whole thing ! Regarding the public method `compare()` i now understand that to be necessary because method implementations of implemented interfaces have to be public. But if it were some other method , having it as public would really mean no big deal. Right ? – Somjit Sep 18 '13 at 09:52
  • yes then it wont be of that use. Its safe to keep them private then – Narendra Pathai Sep 18 '13 at 09:53
  • regarding the part : "You should keep class non-static only when you really need the instance of outer class to get the instance of inner class." ,would be much obliged if you could elaborate this a bit .. – Somjit Sep 18 '13 at 09:58
6

This class implements Comparator and so must implement its methods. The implementation methods can't be static. Also, since interface methods are implicitly public, they must be declared public, regardless of the containing class's visibility. Try not doing so and it will fail to compile. This is certainly the reason it is declared public here -- it can't not be.

This is true regardless of whether the containing class is static or public. Here, it could be either of those things and the method inside would still have to be public and non-static.

Other methods that don't implement an interface could be private, and, logically probably should inside a private class as there would be no point in declaring it otherwise -- but it would be allowed by Java syntax.

Sean Owen
  • 66,182
  • 23
  • 141
  • 173
  • When You say no point in declaring it otherwise , so that means even if i have a public method ( other than something that's an implementation method for an interface ) , that public method is gonna be private since its inside a private class right ? – Somjit Sep 18 '13 at 09:36
  • From a Java/bytecode perspective it would technically still be `public`, but, this would have no additional meaning. The only way to reference it is via the class, and that is not visible elsewhere if it's `private`. – Sean Owen Sep 18 '13 at 09:37
  • I understood the "public inside private" part , can you give a little explanation regarding why `ROrder` is static here ? I read somewhere that statics are prescribed when the method in question does not alter anyone's state... i think i understand that a bit , but would love some clarification/explanation... – Somjit Sep 18 '13 at 10:05
  • 1
    This is probably better answered already in other SO questions. It is `static` because an instance of `ROrder` isn't logically tied to an instance of the containing class. It's separate and does not operate on the containing class's instances. You could say `static` is really the right default, and you make non-`static` only when required. – Sean Owen Sep 18 '13 at 10:47
5

All private members (fields, classes, whatever) are only visible inside the class. So, it doesn't matter what visibility you give a method of a private class - all methods will only be visible inside the containing class, because the class itself is private.

If the inner class implements an interface or extends a class, overridden methods may not have less visibility than the declaration in the super type, so that's one reason to have public methods in a private inner class.

However, although the syntax allows private classes to have public methods, it won't increase the visibility of those methods sufficiently to be visible outside the containing class. There are several examples in java of modifiers being legal but having no effect, such as inner interfaces being implicitly static (whether or not the static keyword is used).

Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • The broad overview was very helpful.. will be easier for me to remember. However when you say ".. so that's one reason to have public methods.." , are there more ? – Somjit Sep 18 '13 at 10:10
  • I can't think of one off hand. – Bohemian Sep 18 '13 at 12:47
1

This class is private because developer did not want to ROrder be instantiated in other place. But an instance can be accessed through the constant R_ORDER from other classes.

The method is public for two reason : first, compare is defined in the Comparator interface. Second, as R_ORDER is accessible from other classes, it is more than convenient to be able to call a method on this object. In this case, it is compare.

Finally, if the class was not static, it would keep a reference to the parent class, which is almost always not needed

Jerome
  • 2,104
  • 1
  • 17
  • 31