views:

101

answers:

6

Hi all,

I am not able to understand why this code doesnt compile :

 class A {
    public static void main(String[] args) {
        System.out.println("hi");

    }
}

    private class B {
     int a;
    }

I am saving the contents in a file named A.java - and I get an error :

modifier private not allowed here // where I have defined class B

This happens both when I try B as private and protected. Can someone please explain me the reason behind this ?

Thanks !

A: 

Just have no private/protected modifier at all.

djna
I meant to say I have tried both private and protected separately, but it doesnt work in both cases
Raj
I am just experimenting with access control, I just want to know the reason of error.
Raj
A: 

B needs to be private to something. Place it within the definition of class A or create another file, B.java, and define it there, but then it cannot be private.

linuxuser27
Is that a rule in Java to make a class/ variable private or protected "to something" ? Cant we have standalone classes/ variables private or protected ?
Raj
My statement was more abstract than conceptual. The fundamental issue was that you were declaring another class in the A.java file. It appeared that you wanted to make B private to A or within 'something'. However your statement regarding can we have stand alone classes private or protected doesn't really make sense because the modifiers only have context when they are relative to something.
linuxuser27
A: 

Make the B nested of A, like this:

 class A {
public static void main(String[] args) {
    System.out.println("hi");

}
private class B {
    int a;
}}

Or move B to a separate file. Also you can stick with default access level, this way the class can be accessed only from within the package:

 class A {
  public static void main(String[] args) {
    System.out.println("hi");
 } 
 }

 class B {
     int a;
 }
Konstantin Burov
I dont want to nest, or move to different file. I just want to know the cause of error
Raj
The error is actually obvious. If you don't do it nested or separate file the class will not be accessible from anywhere, since it is private. You cannot make it public also, cause java has a restriction of one public top-level class per file.
Konstantin Burov
But what about protected ?
Raj
Protected makes no sense for top level classes. Since if it has default access level (no modifier specified) it is accessible from withing the package, if public -- it is also accessible from outside the package. Protected doesn't adds anything to this. Btw I forgot to notice that you may use default access level. See the answer update.
Konstantin Burov
Thanks Konstantin !
Raj
A: 

If you don't use the public keyword for the class it will be private by default (visible only within the file).

There can be only one public class per .java file, all the others need to be private. So class A can be public and class B doesn't need any modifiers in your example. The public class name must match the .java file name (eg. A.java can only contain one public class called "A").

Gabor Kulcsar
This is not correct. A top level class with no modifier is *package* private. It can be referred to from any class within the same package.
Andreas_D
+6  A: 

From the Java Language specification:

The access modifiers protected and private pertain only to member classes within a directly enclosing class declaration

So yes, the private and the protected modifiers are not allowed for top level class declarations.

Top-level classes may be public or not, while private and protected ar not allowed. If the class is declared public, than it can be referred to from any package. Otherwise it can only be referred to from the same package (namespace).

A private top level classes wouldn't make much sense because it couldn't be referred to from any class. It would be unusable by definition. private is OK for member classes to make a class referrable to only it's enclosing class.

A protected member class can be referred to from (1) any class of the same package and from (2) any subclass of the enclosing class. Mapping this concept to top level classes is difficult. The first case is covered by top level class with no access modifiers. The second case is not applicable for top level classes, because there is no enclosing class or something else from a different package with a special relation to this class (like a subclass). Because of this I think, protected is not allowed because it's underlying concept is not applicable for top level classes.

Andreas_D
Thanks Andreas, but can you please make me understand why might the Java developers would have imposed this restriction ? I know this question may sound absurd, but I am curious. Thanks !
Raj
OK. Got the logic for private, but what about protected ?? 'Protected' is certainly more open than the 'default' specifier - which has been allowed !
Raj
+1  A: 

A.java cannot contain two classes.

fastcodejava
Yes it can, as long as only one is public (the one that gives the source file its name) and all other non-public (no access modifier, a.k.a package accessible), a source file can contain multiple classes.
Andrei Fierbinteanu
-1, sorry that's just not correct as Andrei explains.
djna