I am writing a simple program:
class Demo{
public static void main(String[] args){
system.out.println("Hello");
}
}
on compilation it gives an error: package system not found.
Why it do so that package not found instead system is a misspelled class name.
System.out.println("Hello");
You need a capital S
Package names are lower case like java.lang.SomeClass, since it's lowercase it assumes you're looking for a package named system.
Why it do so that package not found instead system is a misspelled class name
When you say something.somethingElse the compiler assumes you are doing a packageName.classname. In this case you were intending to access out of the System class, but you could very well be trying to access a package called system that is not present (in the classpath for instance). So it is a guess from a compiler.
And (I guess) it is so because this is the better guess. Let's say the compiler said class not found. You might be happy. But tons of others doing Java.util.List (instead of java.util.List) would complain "I was trying to access the java.util package but misspelled it. The compiler wrongly says Missing class name.
Update (for the sake of completeness)
From #paxdiablo's answer below:
The reason why the compiler is assuming it's a package name rather
than a class or variable name lies in section 6.5 of the JLS,
"Determining the meaning of a name"
It's System with a capital S:
class Demo {
public static void main (String[] args) {
System.out.println ("Hello");
}
}
The reason why the compiler is assuming it's a package name rather than a class or variable name lies in section 6.5 of the JLS, "Determining the meaning of a name":
The meaning of a name depends on the context in which it is used. The determination of the meaning of a name requires three steps.
First, context causes a name syntactically to fall into one of six categories: PackageName, TypeName, ExpressionName, MethodName, PackageOrTypeName, or AmbiguousName.
Second, a name that is initially classified by its context as an AmbiguousName or as a PackageOrTypeName is then reclassified to be a PackageName, TypeName, or ExpressionName.
Third, the resulting category then dictates the final determination of the meaning of the name (or a compilation error if the name has no meaning).
Your particular use is an AmbiguousName, due to 6.5.1:
A name is syntactically classified as a MethodName in these contexts: (1) Before the '(' in a method invocation expression; (2) some other irrelevant contexts.
A name is syntactically classified as an AmbiguousName in these contexts: (1) To the left of the '.' in a qualified ExpressionName; (2) To the left of the '.' in a qualified MethodName; (3) some other irrelevant contexts.
Based on your code, system.out.println(whatever) is a qualified MethodName preceded by an AmbiguousName. Later on in the process, 6.5.2, the reclassification, mentioned earlier, takes place:
If the AmbiguousName is a qualified name, consisting of a name, a '.', and an
Identifier, then the name to the left of the '.' is first reclassified, for it is itself
an AmbiguousName.
If the name to the left of the '.' is reclassified as a PackageName, then if
there is a package whose name is the name to the left of the '.' and that
package contains a declaration of a type whose name is the same as the
Identifier, then this AmbiguousName is reclassified as a TypeName.
Otherwise, this AmbiguousName is reclassified as a PackageName.
A later step determines whether or not a package of that name actually exists.
Because the reclassification walking up the tree (from println towards system) never results in a TypeName, the default reclassification to PackageName is always done.
That's why the error message you see is about a missing package rather than a missing class.
THe only error in this code is that you have written small s instead of capital S in System.out.println("Hello");
The most case in which you get an error Package system not found in system.out.println(" "); is because, you have to give your file name as "nameofpublicclass.java".
In this example, file name must be "Demo.java".
I think that will solve the error.
The compiler says system package not found...
Because it can't find a package called system ( starting with a lower case s.)
It might be able to find one called System, but that's not what your code asked for.
The compiler almost never guesses.
Related
I am using JavaParser (open source) to parse the following code.
package testfiles.simple.tricky.before;
import testfiles.simple.before.InnerClassSample;
public class InnerClassReference {
public void ref(InnerClassSample.MyInnerClass myInnerClass, java.util.List<Long> list) {
int i = 0;
}
}
Under the methodDeclaration node named ref, I get the parameter node hierarchy as follows:
// myInnerClass
Parameter
ClassOrInterfaceType:
ClassOrInterfaceType:
SimpleName: InnerClassSample
SimpleName: MyInnerClass
SimpleName: myInnerClass
// list
Parameter
ClassOrInterfaceType:
ClassOrInterfaceType:
ClassOrInterfaceType:
SimpleName: java
SimpleName: util
SimpleName: List
SimpleName: list
I need to find the fully qualified names for each parameter. So for myInnerClass I would get testfiles.simple.before.InnerClassSample$MyInnerClass and for list it would be java.util.List.
I understand that normally one would write List<Long> and put an import statement instead of writing java.util.List<Long>, however, I need to handle cases where the FQN is written in the parameter.
Now my question is, is there a way statically to distinguish if such a parsed tree is a type for a nested class, or it is merely a fully qualified name of a class?
I have thought about distinguishing by checking if the SimpleName starts with a lower case letter (meaning it is a package name), but, this is only a convention so we cannot assume safely that a developer would always start a package name with a lower case letter, or start a class name with a capital letter, hence I do not think this is a good way.
Any idea or insight about this matter would be much appreciated.
It is unfortunately not possible to distinguish between the name of a top-level class and the name of a nested class from only the qualified name, or by analysing only a single source file. At least not in all cases.
To make that distinction you have to perform a resolution step, to find out what the names reference. This necessarily involves multiple source files.
The resolution step probably involves looking at the information in the AST or the class files of the referenced elements.
Note: Even if the resolution step involves multiple source files that information is still static information.
In JAVA, class name must always be the same as file name, but sometimes file contains multiple classes. Only single class(or interface) in file can be public, and it must have the same name as file. But how is the file name determined if it has multiple classes (or interfaces) that are not public?
interface Foo {}
class Bar{}
Some people seem to be confused about this question
I actually know that it'll work regardless if I choose Foo or Bar as a file name. However what interest's me is if there are some kind of convention of naming the class.
Why don't I name it whatever I feel like it? Because i'm actually writing an application that refactors code, and whenever it renames classes, i need to know how and when to change my filename.
So far i think the right way is:
if class has a public node, use it's name as filename,
else just pick the first node, so in this example Foo would win. So I simplify the question: is this the right way, or is there something more to it?
Quoting the Java Language Specification, section 7.6 Top Level Type Declarations :
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.
So, as you can see, it is not a requirement that "class name must always be the same as file name", as you said it.
It is simply a way to allow some compilers an easy way to find the class source code during compilation.
But, more importantly, it also help humans find the source code. If you see a reference to class com.example.Foo, you know exactly where to find it, because it's going to be in file com/example/Foo.java.
Non-public (package private) top-level classes, can technically be placed in files of any name, and multiple such classes can be bundled in a single file, but that makes them difficult to find. For this reason, I've seen a guideline (don't remember where) that said that you should always put top-level classes in their own file, with one exception:
If the non-public class is only used by one other class, it's ok to place it in the same compilation unit (.java file) as that other class.
Basically this means that you should consider any top-level class, whose name is not the file name, to be "file-scoped", even though it's technically packages-scoped.
There are 2 rules to follow:
1st Rule: The class can have either package (default) or public visibility
2nd Rule: Teh class which you have defined as public must be implemented in a .java source file with the same name, however classes that are non-public can be with other name in source files.
I have checked the following posts already:
https://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.2
and SO post:
Is this a valid java package name?
and
What package naming convention do you use for personal/hobby projects in Java?
I tried creating a package like this:
package 01;
public class Test
{
// ...
}
When I compile I get this:
I:\code>javac 01\Test.java
01\Test.java:1: error: <identifier> expected
package 01;
^
1 error
I am looking for syntactical correctness of the name not the convention.
Is there a oracle/SUN reference that lists out the syntax for a package or does it follow the same rules as for variable names in java? May be a reference in the Java Language Specification saying package names follow the same rules as variable names.
Found it:
If any of the resulting package name components start with a digit, or any other character that is not allowed as an initial character of an identifier, have an underscore prefixed to the component.
In JLS 6.1 Declarations
This links to identifier grammar that Java uses, which applies everywhere identifier is mentioned, including but not limited to package name. So 01 is definitely not a valid package name, since it's not a valid identifier.
Why is the String class capitalized but java and lang are lowercase, another example would be System.out.println, println is a method so lowercase is expected, but why is out lowercase? Am I missing something or does someone not follow their own rules?
Class names have the first letter in Uppercase. Package names are always in lower case as per naming conventions.
java.lang is the package name
String is the Class name
For the System.out.println() it breaks down as this
System is the class name, so the first letter is Uppercase
out is a public static field which is of the PrintStream class so it can be access directly.
println() is a method of the PrintStream class
Example of usage would be System.out.println("Hello World");
More information about this can be found in the documentation here http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#out
System.out.println() here the whole thing is not a method name. Here only the println() is a method name and it is in lower case. System is the class name and out represent an standard object which I don't need to create implicitly.
More over java.lang is a package name and String is the class name. java.lang.String as a whole is not a class name, it's fully qualified class name.Each group in a package name always starts with lowercase.And it's customary in java to write the class and package name by this convention.
"Naming conventions make programs more understandable by making them easier to read. They can also give information about the function of the identifier-for example, whether it's a constant, package, or class-which can be helpful in understanding the code."
Reference: Java Naming Conventions
So, in your example "java.lang" is the package name and "String" is the class name which followed Java Naming Conventions.
I could not execute my java program by a command line, although the Eclipse's "Run" menu executed it. While examining the problem, I happened to find that changing the name from HELLOWorld to HelloWorld fixed the problem for my particular case. Does really Java's naming rule restrict such names?
Your file name must match to the public class name that you defined in that file. May be this might be the case in your scenario.
The Java Language Specification states the requirements for a class name (which is an Identifier). To sum it up: it must begin with a letter or underscore, and the remainder may contain letters or digits.
Thus, HELLOWorld is a valid classname, however, if your class is public, the filename and classname must match (you will receive a compilation error otherwise).
in one word, Yes
public class name must be same as class file name
Yes. The name of your public class must be same as the name of your filename i.e .java file.However you may have number of other classes also.