This question already has answers here:
Why are modifiers allowed for a package when they don't seem to do anything?
(2 answers)
Closed 9 years ago.
Please see the sample:
private package com.xm.aws;
import static com.xml.aws.PcgTest.test;
public class PackageTest {
public static void main(String[] args) {
test(args);
}
}
What does the private tell me about the package?
Let's not confuse this with package-private or other access modifiers that can be added to classes, methods and fields.
The Java language specification clearly states:
6.6.1. Determining Accessibility
A package is always accessible.
Looking at that, the only answer, that comes to my mind is, that (some) compilers don't treat this as a compiletime error but that it is completely meaningless. It is not possible to restrict accessibility to a class or package that way (and every package is always accessible).
Another section from the java language spec:
7.4.1. Named Packages
A package declaration in a compilation unit specifies the name (§6.2)
of the package to which the compilation unit belongs.
PackageDeclaration:
Annotationsopt package PackageName ;
So the keyword may be preceeded by annotations. But the access modifiers is not part of the package declaration. And even if we expand on "Annotations" we won't find access modifiers here.
Another reference, according to JLS 18. Syntax the only thing allowed to precede package is an Annotation.
CompilationUnit:
[[Annotations] package QualifiedIdentifier ;]
{ImportDeclaration} {TypeDeclaration}
The code sample you have provided is not valid in java. The private access modifier can be applied to members and methods, including inner classes. Your code compiles in Eclipse, but is rejected by Oracle's own compiler.
In fact, the byte-code generated by Eclipse for this java code, is exactly the same with or without that private keyword. This shows that this is probably an Eclipse bug where it ignores the text before the word package during compilation.
What you have probably read or heard, is the phrase "package-private", which means that nothing outside the package can access the class or member. You do this by not using any access modifier on the class itself. Not by using the private keyword on the package.
If you add private before the package name this will be compiler error
Though package is not the highest degree of Encapsulation in Java which is achieved using private keyword, it still second best option and must to encapsulate whole functionality rather than just a class.
In short, Access modifiers are not part of the package declarations
Refer this link
Looks to me like it is only happening in eclipse. When i compile the code though javac command through command prompt, i get this compile time error:
error: class, interface, or enum expected
Looking at the post here, looks like eclipse uses its own jdk:
Do I need to install java sdk if I have eclipse
Writing "private package" and "package" is the same. They identify the same access level (the dafault one).
The private modifier specifies that the member can only be accessed within its own package (as with protected).
Related
I know these questions may sound stupid, but in Java, what are Auxiliary classes, how does some one write one, and how does the compiler know that something is an Auxiliary class?
Edit:
The reason I ask this is because the compiler is generating a warning regarding an object in an external library, and I want to know why.
Edit 2:
Here is the compiler warning for those who want it:
warning: auxiliary class Pattern in jregex/Pattern.java should not be accessed from outside its own source file
As descried in Java specification here, you can specify more than one class in one .java file. The class which name matches .java file name will be the main class which can be declared public and be visible to other classes. All other classes in the file therefore are "auxilary" classes. Auxilary class can NOT be declared public and (as #trashgod rightfully pointed out) therefore they only be declared with package-private access. For instance for AClass.java file:
public class AClass {
private AuxilaryClass a;
}
class AuxilaryClass {
private int b;
}
AuxilaryClass class can't be public and is not visible outside this AClass.java file.
However, using auxilary classes considered extremely bad style and against Java Code Convention. Please use separate or inner classes if really needed.
Edit: The term "Auxilary" is not Oracle/Sun official terminology. It has been introduced (or used) here: http://www.youtube.com/watch?v=miTM9rY3He0 and/or here: http://doc.sumy.ua/prog/java/langref/ch05_03.htm
An auxiliary class isn't any kind of official or technical thing as far as I know. Someone might describe a class as auxiliary if it were addressing a secondary concern, or something, but the compiler doesn't have any idea what an auxiliary class is, and neither do I.
In general, if you have error messages from the computer, please paste them in their entirety. If you think the compiler is upset about an auxiliary class, paste the error message: someone else will be able to make sense of it, whereas currently it's being filtered through some kind of confusion that's made you think auxiliary classes are a real thing!
Is this code valid?
public abstract class A {
protected static final String c = "my const";
}
#myAnnotation(value=A.c)
public class B extends A {
}
Eclipse with JDK 1.6.0.23 accepts this, but Maven 2.2.1 with JDK 1.6.0.23 shows me the following compile error:
c has protected access in A
Thanks to the comment from #adranale I found a different answer in the Java Language Specification section on Access Control. I don't think it should work this way, but the relevant text regarding "protected" reads
Let C be the class in which a protected member m is declared. Access is permitted only within the body of a subclass S of C.
The body of a class is all the code in curly brackets. Class anotations are outside the curly brackets, so they don't have access. Interestingly, this logic would not apply to method, parameter, field or local variable annotations which are inside the class body.
I think I see what is happening here. An instance of an annotations is effectively an interface with a unique static initializer. The only things the annotation spec adds on top are syntactic sugar and a link to the method, class or field. So when you type value=c.A that is almost like adding a static initilizer to the annotation. The annotation is not a subclass of A, so access is denied. Protected access includes package access, so when you move A into the same package as B the annotation is also in the same package as A. It gets access. Very good question and I think the behavior should be the same for both compilers. I think Eclipse will let you customize what it treats as an error so you might be able to make them agree to both use the undesirable, more restrictive behavior.
The Annotation you are trying to fill with the "const" tries to access the class from outside by using protected that can't work. Eclipse uses it's own compiler so you should try to make clean rebuild in Eclipse to see if it's working. I assume it will not.
This code will compile only if both A and B belong to the same package.
For example I have a file name call "A.java". Here its structure:
public class A{
}
private class B{
// no error
}
public class C{
//error : must declare at different file
}
I think this is Java rules. But, I really want to know: WHY java need to do that.
Thanks :)
You can find in section 7.6 of the JLS:
When packages are stored in a file system (§7.2.1), 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 compiler for
the Java programming language or an implementation of the Java virtual
machine to find a named class within a package; for example, the
source code for a public type wet.sprocket.Toad would be found in a
file Toad.java in the directory wet/sprocket, and the corresponding
object code would be found in the file Toad.class in the same
directory.
There can only be one public class per .java file, as public classes must have the same name as the source file.
From your example: if you have file "A.java", only class A can be public.
It is defined in the Java Language Specification.
public class A{
}
private class B{
// no error
}
This shouldn't even work (see Java Language Specification):
It is a compile-time error if a top level type declaration contains
any one of the following access modifiers: protected, private, or
static
Are you sure you haven't declared class B as an inner class?
It doesn't make sens to declare a top-level class as private, since private restricts the visibility of members to the enclosing top-level class/interface. If your class is a top-level class (whether or not in its own file), you'd at least want package-level visibility (no modifier at all).
well,
you cannot have structure is a file called 'A.java' because you intended public class is named 'ClassA', then the file name must be ClassA.java. Now, as far as I understand, the idea behind this restriction is just to be organized. So you can have the physical origin of every class.
Without this restriction u can have a for example 'ClassC' coming from 'nowhere', and it could be really difficult to track the source code.
regards
In any Java file, why can we have only one public class whose name is same as the Java file name?
It forces all Java code to be organized in a certain way, which in the long run helps improve code readability.
The Java designers chose a strict approach that enforces their idea of good design practices, and this is part of that theme. Contrast that with the anything-goes attitude in Perl.
According to this source, it is for efficient compilation :
In the sidebar it explains why: "This
restriction is not yet enforced by the
compiler, although it's necessary for
efficient package importation"
It's pretty obvious - like most things
are once you know the design reasons -
the compiler would have to make an
additional pass through all the
compilation units (.java files) to
figure out what classes were where,
and that would make the compilation
even slower.
The same applies also for imports of source files in IDEs. Another reason would be reasonable source sizes.
These are the rules. Although it is not quite true. You can define internal classes inside you "main" class like this:
public class A {
public class B {
...
}
}
Courtesy of Dr Heinz Kabutz and his excellent newsletter....
Why is each public class in a separate
file?
This is a question that I have
frequently been asked during my
courses. Up to now I have not had a
good answer to this question. In
section 1, we read: "Although each Oak
compilation unit can contain multiple
classes or interfaces, at most one
class or interface per compilation
unit can be public".
In the sidebar it explains why: "This
restriction is not yet enforced by the
compiler, although it's necessary for
efficient package importation"
It's pretty obvious - like most things
are once you know the design reasons -
the compiler would have to make an
additional pass through all the
compilation units (.java files) to
figure out what classes were where,
and that would make the compilation
even slower.
We can have only one top level public either class or interface in any java compilation unit ( .java source file ).
But there can be any number of default classes/interfaces per src file.
why:
JLS leaves the option to the java compiler. And most of the compiler implementations force to have file name same as :
(1) the public class/interface name
(2) if there is a main method and no public class then any name
(3) If there is main method and public class then main method should be in that public class
(4) if there is no public class and no main method then any valid name which may or may not be matching with the class/interface names in the file.
From (2): If two public classes allowed, we should give the file two names which is terribly meaningless to file system.
From (3): If two public classes allowed, we should have two main methods which is terribly meaningless to java
Hence a Java source file can have one only public class.
I think the above 4 points are forced by compiler to make the job of both compiler and jvm to find particular java source file or class file easy-so-quick for the compilation/loading/linking. Java has such built in restrictions which developers should follow to have better programming.
Source: My readings and understanding.
To understand the basic reason behind these restrictions, let's suppose compiler doesn't give compile error for not naming file name same as public class name.
Suppose there is a package A
A
/ \
file1.java file2.java
file1.java
package A;
class file1
{
public static void main(String args[])
{
}
}
public class file3
{
public static void main(String args[])
{
}
}
Now as we know that a public class can also be accessed outside the package, now it will become the responsibility of a developer to make it accessible to the outside world. Let's see how:
Suppose package A is containing only Java files(no class files) and some class outside the package A tries to access public class file3, compiler will first try to find file3.class ( not available ), then it will try to find file3.java ( not available ). So even though file3 class is public in nature, it is not visible to the outside world. So if a compiler puts the restriction that if a file is containing public class, it should be named same as the public class name, then above issue can be resolved and the developer won't have to think of exposing public class to the outside world.
Compiler also puts the restriction that there should be atmost one public class per Java file, so that every public class can be accessed by the outside world.
Java utilizes this convention to find class/interface bytecode by starting at the classpath and scanning for the package hierarchy in subdirectories. Filesystem representation of this hierarchy also enforces some basic rules.
Any two Java classes or interfaces
in the same package cannot have the
same name. File names would
conflict.
Any two Java packages in
the same parent package could not
have the same name. Folder paths
would conflict.
A class has visibility to all classes in the same package without modification
to the classpath.
To have an understanding between the compiler and the programmer.It is a rule that the source code must have atmost one public class and that class must contain the main function.So without any confusion/restriction the compiler can access(public) the class and name the class name to the class file.Also since this class contains the main(), executing the class file will give correct flow
Public modifier with a class is exposed to the world that means any other class which is outside of the package can also access it to resolve dependency.
Now this dependency chain containing multiple classes are verified two times - one is while compilation ( one level of dependency is verified) & other one is while execution ( whole dependency chain is verified ).
Now suppose there is public class (class A) whose source file name is something different from class name. Now if some other class (say class B) depends on it , then while compilation of class B , java compiler will surely check where that class A is located & for that compiler has to go thru all the packages in search of class A ,which is time consuming.
Now suppose in the same scenario we give source file name of class A as A.java , then while compiling class B , compiler will search for class A & for that it only need to find source file whose name is A.java , so it doesn't need to go thru all packages ( which may contain multiple classes) it will now only search that package in which a source file A.java is present.
So from compilation time , performance point if view one source file should have one public class.
It enables a more efficient lookup of source (.java) and compiled (.class) files during compilation (import directive) and a more efficient classloading during execution. The idea being: if you know the name of a class, you know where it should be found for each classpath entry. No indexing required.
I think that this may be a possible reason.
There can be only one public class in a java file because the name of java file is same as the name of public class.And obviously we can't have a file with two different names.
It is how it has been designed and I am not sure if the reason is documented. But here is a good reason on why it is done that way. Let's assume we have two public classes Y & Z in a file named Y.java. Now, let's assume a different class X is using Z. Now, when we compile X, the compiler first tries to locate Z.class and if it cannot find it, then it tries to locate Z.java so that it can compile it automatically. But, since we only have Y.java, the class Z cannot be located and hence we get a compilation error. So, we do need to place them in separate files.
Class A{
}
public Class B{
}
So this is correct becoz A is not public and compiler will not confuse that which class compiler should execute.
public Class A{
}
public Class B{
}
So this is incorrect becoz here compiler get confused which class should execute becoz both are public.
The following statements seem to disturbingly function:
robert#neghvar:~/tmp> cat org/foo/Bar.java
public class Bar {
}
robert#neghvar:~/tmp> javac org/foo/Bar.java
robert#neghvar:~/tmp> javap org.foo.Bar
Compiled from "Bar.java"
public class org.something.Bar extends java.lang.Object{
public org.something.Bar();
}
Although the Bar class file is in the org/foo directory and declares the org.something package, the compiler does not complain. I was under the impression that java mandated a directory hierarchy which follows the package name. Was I mistaken? If so, what are the consequences of mixing up package names?
The source directory structure is not required to follow package naming (even though it almost always does by convention.)
I think the Sun/Oracle javac,javap,java,etc. tools (and all other Java implementations that I know of) are what mandate the subdirectory per package name component rule (along with the default class loaders). I couldn't find anything authoritative, but it doesn't seem to be a requirement of the Java language specification:
http://java.sun.com/docs/books/jls/third_edition/html/packages.html
It's purely convention. The compiler will use the package names.
Having said that, it's not usually a good idea to break with this convention. It'll cause inconsistency (the classes generated will be in directories following the package) and some confusion!