0

I heard that a .java file can only have one public top-level class.

Must the accessibility of any other top-level class in the same .java file be either private or protected?

Why

public class MyClass {
    public static void main(String args[]) {
    }
}

 private class C{}

has error

/MyClass.java:6: error: modifier private not allowed here
 private class C{}
         ^
1 error

Thanks.

Tim
  • 1
  • 141
  • 372
  • 590
  • Here is the problem: "each file can contain at most one top-level class ." That's not true. Where did you find this statement? A source file can have any number of Java classes at the top level, as long as at most one of them is `public`. – Erwin Bolwidt Nov 03 '17 at 04:09
  • https://stackoverflow.com/a/47088236/156458 – Tim Nov 03 '17 at 04:11
  • I reverted back to my original question. My update to respond to https://stackoverflow.com/a/47088236/156458 wasn't my original question. What's your thought about my original question? – Tim Nov 03 '17 at 04:13

3 Answers3

2

A Java file can only have one top-level class, which means you can nest classes. You are currently trying to create two top-level classes. A nested class would look like,

public class MyClass {
    public static void main(String args[]) {
    }
    private class C{}
}

And has the name MyClass.C (here MyClass is the top-level class, and C is an inner class). In the case of top-level classes, the source file name must match the declared name of the top-level class. This is in contrast to languages like C, which do not enforce the naming scheme of source files.

As @Erwin Bolwidt pointed out in the comments, you can (although it's a bad idea) have

public class MyClass {
    public static void main(String args[]) {
    }
}
class C{}

But only classes in the same package as MyClass can access it.

Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • 1
    @Elliot - that's not right. A source file can have any number of top-level classes in it, as long as at most one of them is `public`. Package-level access classes can be put in the same source file as public classes. It's not a good idea but it's one of these things inherited from the very first version of Java. – Erwin Bolwidt Nov 03 '17 at 04:11
  • @ErwinBolwidt I did not know that. And (as you say) only package level (not `private` for example). – Elliott Frisch Nov 03 '17 at 04:16
2

Must the accessibility of any other top-level class in the same .java file be either private or protected?

Obviously not, as your questions compilation error has already told you that private is not valid for a top-level class.

The Java Language Specification 7.6 Top Level Type Declarations answers your question:

In the absence of an access modifier, a top level type has package access: it is accessible only within compilation units of the package in which it is declared (§6.6.1). A type may be declared public to grant access to the type from code in other packages.

It is a compile-time error if a top level type declaration contains any one of the following access modifiers: protected, private, or static.

So, neither private nor protected is even allowed for top-level classes.

The specification goes on to say:

If and only if packages are stored in a file system (§7.2), the host system may choose to enforce the restriction that it is a compile-time error if a type is not found in a file under a name composed of the type name plus an extension (such as .java or .jav) if either of the following is true:

  • The type is referred to by code in other compilation units of the package in which the type is declared.

  • The type is declared public (and therefore is potentially accessible from code in other packages).

This restriction implies that there must be at most one such type per compilation unit. This restriction makes it easy for a Java compiler to find a named class within a package. In practice, many programmers choose to put each class or interface type in its own compilation unit, whether or not it is public or is referred to by code in other compilation units.

As you can see, a public top-level class must be named the same as the source file. There can then of course only be one public top-level class per file.

Any non-public top-level classes must be what is commonly referred to as package-private, i.e. it must not have an access modifier.

Access modifiers are defined in Chapter 6. Names:

In the absence of an access modifier, most declarations have package access, allowing access anywhere within the package that contains its declaration; other possibilities are public, protected, and private.

Community
  • 1
  • 1
Andreas
  • 154,647
  • 11
  • 152
  • 247
1

Inner class can have any access modifier, but outer class can only have either public or default modifier.

eg :- public class A or class A

To know more about access modifiers in Java you can check this link In Java, difference between default, public, protected, and private

Arun Sudhakaran
  • 2,167
  • 4
  • 27
  • 52
  • Thanks. What's the default modifier? `public`, `private`, or `protected`? – Tim Nov 03 '17 at 04:03
  • If you dont specify any modifier, then it is considered as default. Accessible through out the current package. – Arun Sudhakaran Nov 03 '17 at 04:04
  • What is default: public, private or protected? – Tim Nov 03 '17 at 04:11
  • The default is none of `public`, `private` or `protected`. It's simply the default, sometimes called `package-private`. See the [doco](https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html). – dave Nov 03 '17 at 04:22