Cannot find symbol error when importing enum class - java

So I'm facing a cannot find symbol error when static importing an enum in a class that depends on it. They are both in separate files within the same directory. I've omitted an explicit package name.
TokenType.java
// No imports
enum TokenType {
ADD, MINUS, MULTIPLY, DIVIDE,
...
}
Scanner.java
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import static TokenType.*; // <--- (error: cannot find symbol)
class Scanner {
private static final Map <String, TokenType> keywords; // <--- (no error; javac can resolve the class name just fine)
static {
keywords = new HashMap<>();
keywords.put("+", ADD); // <-- (error: cannot find symbol, which makes sense)
keywords.put("-", MINUS);
...
}
...
}
I'm just not sure how to proceed. The names are all typed correctly, and there is only one TokenType class so there isn't a class conflict. My other classes in the project directory have no nested classes, do not extend/implement from other classes, or import libraries that have a TokenType class in their dependencies. I've cleaned my directory of all stale classes before each compile, and even changed the order in which I'm calling javac. Any help would be wonderful, thank you.
EDIT: Solution was to put them in a named package. Java doesn't allow imports from default package.

From the fact that the compiler can resolve the simple name TokenType in Map <String, TokenType>, it seems like TokenType is declared in the same package as Scanner.
You also said that you "omitted an explicit package name", which implies that both of these classes are not declared in the default package (static imports are not possible if they are in the default package), but some package with a name. Let's suppose that both of them are in
package com.example.foo;
Then you need to do:
import static com.example.foo.TokenType.*;
Note that even if you are in a location where the type is accessible with its simple name, you still need to use its canonical name (basically with the package name fully written out) in a static import declaration., and the name has to be qualified (in the form of X.Y), which is why classes in the default package don't work.

Related

Importing and Packages

I'm not quite sure what I'm doing wrong, here. I have two files in a directory, let's call them FileA.java and FileB.java.
FileA.java has a definition along the lines of:
package com.domain.package;
import stuff;
import package.FileB;
public class FileA extends Blah implements Listener {
/* global vars */
/* methods */
}
FileB.java is my data object class, which I'd like to reference from FileA.java thusly:
Map<Object, FileB> varname;
to be used along the lines of:
varname = new HashMap<Object, FileB>();
FileB.java, on the other hand, is defined as such:
package com.domain.package;
import stuff;
public class FileB {
/* global vars */
public FileB() {
/* stuff */
}
}
Why am I getting:
FileA.java:20: package package does not exist
import package.FileB;
? Rather, how do I make it work?
Because both files are in the same package (com.domain.package), you should not need to import FileB at all. You should be able to reference it directly.
Additionally, please ensure that both FileA and FileB are placed in their package folder: com/domain/package.
The package of FileB is com.domain.package. You are trying to use package.FileB instead.
package is a reserved word, don't use it as part of a package name. If you try to add a package with "package" as part of it in Eclipse, you will get an error message:
Invalid package name. 'package' is not a valid Java identifier
Rename the package, then remove the import statement. You don't need to import a file that's in the same package as the one it's referenced in.
#rgettman has the correct solution. Compiling both files using javac FileA.java FileB.javasolves this issue. You can also use his suggestion: javac *.java

Import a single class in Java

Simple question but even though googled it a lot I could not find the answer.
Is it possible to import a class outside a package?
Let's say I have 2 folders A and B with a .java file in each, is it possible by using the clause import to import the class contained in A? import A.Aclass ? or it's mandatory using package syntax whenever there is the keyword import?
Yes it is possible to import the class with the import statement. For better understanding let's assume that you have three folders foldera, folderb and folderc where foldera contains a .java file named "ClassA.java", folderb contains another .java file named "ClassB.java" and folderc contains a .java file named "ClassC.java". Now, if you want to uses the member data and operations of "ClassA.java" in "ClassC.java" you can use the import statement as shown below:
import foldera.ClassA
If you want to use the member data & operations of "ClassB.java" in "ClassC.java" it is also possible with the import statement
import folderb.ClassB
As per the java source file declaration rule, if the class is a part of a package, the package statement must be the first line in the source code file, before any import statements that may be present. In this example, the first line of "ClassC.java" source file must be package folderc since it is located in folderc. Similarly, the first line of "ClassA.java" source file must be package foldera, and the first line of "ClassB.java" source file must be package folderb.
Hope now you are clear with the concept!
Thank you...
Well, if the class is defined to have a package a; then you need to import the class with the package name. If you have two packages which contain a class with the same name, then in your class which needs to invoke each of them, you will need to use a fully-qualified name. For example:
import a.Foo;
import b.Foo;
public class Bar
{
public static void main(String[] args)
{
a.Foo aFoo = new a.Foo();
b.Foo bFoo = new b.Foo();
}
}
Alternatively, if you have two packages with classes of the same name, you can simply skip importing them, but rather -- using them by their fully-qualified names (FQN-s).
If the class does not have a package ...;, then simply import it as:
import Foo;
However, if you have two packages (from different libraries) which contain classes with identical FQN-s, then the first one on the classpath will be picked.
Please, bear in mind that the convention for naming packages is to use lowercase letters and for classes -- the name should start with an upper case letter for each word in the class' name.
Yes it is possible.
If you have the following:
Package: PackA
Class: ClasA
Do:
import PackA.ClassA; //Import the class
OR
import PackA.*; //Import all the classes within the package
yes it is possible just import the package
syntax
import pck.ClassA or import pck.*
Yes, you have to use package syntax.
importing all class inside folder A.
import com.pack.A.*;
importing specific class inside folder A.
import com.pack.ClassName;

import static without package name

Consider the following simple example of code:
public class TestStaticImport {
static enum Branches {
APPLE,
IBM
}
public static void doSomething(Branches branch) {
if (branch == APPLE) {
System.out.println("Apple");
}
}
}
If we will try to compile this code, we will get the error message:
java: cannot find symbol
symbol: variable APPLE
location: class TestStaticImport
This could be solved by introducing static import of this enum:
import static ... TestStaticImport.Branches.*
But in this moment incomprehensible things (for me) begin:
this solution works fine, everything is well compiled, until class TestStaticImport will be moved into empty root package, i.e. there isn't any
package blablabla; in the top of this java file;
Code line: import static TestStaticImport.Branches.*; is highlighted as valid code in my Intellij IDEA (name of IDE doesn't matter, just for information), but when I try to compile such code following error appears:
java: package TestStaticImport does not exist
So, there are actually two questions:
1) Main question: why is it impossible to import static from empty directory?
2) What is another way (if it exists) for allowing in code references to enum's fields using just their names (i.e. APPLE instead of Branches.APPLE), except static import?
P.S. Please, don't tell me, that empty packages is ugly style and so on. This question is just theoretical problem.
The Java language specification forbids any imports from the unnamed package:
A type in an unnamed package (§7.4.2) has no canonical name, so the
requirement for a canonical name in every kind of import declaration
implies that (a) types in an unnamed package cannot be imported, and
(b) static members of types in an unnamed package cannot be imported.
As such, §7.5.1, §7.5.2, §7.5.3, and §7.5.4 all require a compile-time
error on any attempt to import a type (or static member thereof) in an
unnamed package.
In ancient times, the Java inventors had to map Java types to files so the compiler could do some real work. They decided to map packages to folders and types to files. That worked pretty well. It especially set the emotional background for newcomers: "I hate you. Don't mess with me." But I digress.
The default package is a problem, though, since it doesn't have a well defined folder. If you have package com, you know that there is a folder com somewhere but what's the name of the folder for the default package?
So the designers decided that import and default package don't mix. In fact, you get an error when you try to import anything that has no package (i.e. import TestStaticImport without the static and * would also fail). See How to import a class from default package
So the problem isn't the static import but that you try to import from the default package.
Like some other corner cases in Java, there is no solution.
see also: In Java- "Static Members of the default package cannot be imported"- Can some one explain this statement?

how to implement a java class so that it holds constants for other classes in other files

What is the best way to implement a system to establish program-wide constants? I have a program that spans several files and I want to have a class that stores constants so that they are available for all the other files.
I tried something like this:
in Constants.java
public final class Constants{
private Constants(){}
public static final String EX = "mas";
}
and in test.java
import Constants.*;
public class test{
public static void main( String[]args){
System.out.println( EX );
}
}
but I get the following error
test.java:1: error: cannot find symbol
import static Constants.*;
^
symbol: class Constants
Constants.java and test.java are in the same dir.
You can not import from the default package. See Java Language Specification
Put the class in a package.
You can't import classes without a package (also called the default package)
If these two classes are in the same package, you do not need to import.
Remove the import statement for Constants class
In your test class, use the following line: Constants.EX to get the value of EX.
You'll need to preface your reference to Constants in the import with the full package name.
For example, if Constants and test are in the package "com.mystuff", you'll need to import as follows:
import static com.mystuff.Constants.*;
Alternatively, since your classes are in the same package you don't really need the import at all - just qualify EX with the Constants class, e.g. Constants.EX instead of just EX.
Any public static final variable will be accessible anywhere without creating an instance of an object. In your case you can access the EX variable with:
Constants.EX;
In general with good object-oriented design the constants which you include in a class should be specific to that object type. For example if you have a Window object its constant might be "aspectRatio" or "height" but it would be inappropriate to have "nameOfUser" in a Window class as a constant. So sometimes making a "universal" Constants class will inherently make you lose sight of which variables truly belong in different classes when following object-oriented ideals.

parent package class accessible from child packge class in java?

In java parent package class accessible from child packge class? please explain me any one?
example
package A.A1.A2 contains class sub
package A contains class sup
Is there anyway to access sup from sub?
pls explain.
i tried import it won't work
Example:
before the program Directory Structure is
package1 contains package1.java --> package2 --> package3 contains PCheck.java
//package1.java
package package1;
public class package1{
public static void main(String[] args) {
}
}
class phelo{
phelo(){
int a;
System.out.println("hai fun freom package 1");
}
}
//PCheck.java;
package package1.package2.package3;
import package1.*; //to import package1.java
public class PCheck {
public static void main(String[] args) {
phelo obj=new phelo();
}
}
class helo{
helo(){
int a;
System.out.println("hai fun from package 3");
}
}
output:
compile time error:package package1.package2.package3 doesnot exist;
for import class from different directory we use import statements but here we need access parent package from subpackage.i tried import it won't work pls explain with an example.
Java does not recognize the notion of a subpackage1. As far as Java is concerned packages a and a.b and a.b.c are unrelated. They are just names.
So, if you want to access a.b.SomeClass from a.b.c.SomeOtherClass, you must either use a fully qualified class name, or add an import to SomeOtherClass
1 - From Java 9 onwards you can use modules to implement abstraction boundaries that are larger than a single package. This doesn't address this question which is about package-private access, but it could be viewed as an alternative to package-private.
As for your example that doesn't compile, I think we need a proper MCVE to understand that. My guess is that you have gotten the file organization for your source tree wrong ...
It is also possible that the problem is that the visibility of the class you are trying to import is wrong (package private), but that wouldn't cause the compiler to say that the package doesn't exist, like you said it does.
In java parent package class
accessible from child packge class?
please explain me any one?
Not the way you're thinking. The directories are hierarchical, but the packages are just distinguishing names.
If a child needs a parent package, or any other outside its hierarchy, it simply needs to import it.
That's why import foo.* doesn't give you access to all sub-package names - packages aren't hierarchical the way directories are.
All answers seem to miss OP's point on package class as everyone seem to suggest importing the class as a workaround.
The answer is: package-level classes (i.e., without explicit access level modifier), are visible ONLY for the EXACT same package.
https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
If a class has no modifier (the default, also known as package-private), it is visible only within its own package
This effectively means that neither parent/child/external packages can view the class.
In object of a.b.c.SomeOtherClass:
List<String> tmp=new ArrayList<String>(Arrays.asList(this.getClass().getPackage().getName().split("\\.")));
tmp.remove(tmp.size()-1);
String parent_package_name=tmp.toString().replace(", ", ".").replaceAll("[\\[\\]]", "");
Class cls=Class.forName(parent_package_name+".SomeClass");
Simply import it:
import A.sup;
Yes I have encountered the same error whenever I tried to access a class in the same package of the source file or the parent package of the source file it is generating a compiled time error , so by trial and error method I came to the conclusion that the packages are not built in a way to support main methods in the classes and they are not built in a way to support importing their parent packages or child packages
default class can be only used within package except subpackage

Categories

Resources