Query about packages - java

I know that import example.* will import all the classes and interfaces in the package example. So is it necessary to use the * only when there are 2 or more classes in the example package?
Because in my program there was only 1 class, xyz, in the package example, and when I tried to use it in other program by import example.*;, the xyz class was not accessible.
Instead if I used it like - import example.xyz, then only it was accessible in other programs. But the usual import java.util.* and other commands work just fine. So is it because they have multiple classes and interfaces in those packages and only then should the * be used?
edit:package code
package myPackage;
public class abcd
{
public void show()
{
System.out.println("this is from package");
}
}
program
import myPackage.*;
class ghg
{
public static void main(String args[])
{
abcd x=new abcd();
x.show();
}
}
error
ghg.java:7: cannot access abcd
bad class file: .\abcd.class
class file contains wrong class: myPackage.abcd
Please remove or make sure it appears in the correct subdirectory of the classpath
EDIT: So i was keeping ghg.java in bin folder of jdk..I moved them out both package and ghg.java and put them in different directory and it worked.

Those import statements are just an indication for the compiler to know where to lookup classes you are using within your source code.
In that sense, this is only about style. There are no good technical reasons to use one or the other style.
But many people consider using "import x.y.*" to be bad practice; they recommend to have "import x.y.Class1", "import x.y.Class2", ...
Reasoning behind that: you, as the human reader are very much interested in understanding the dependencies into other packages. When the wild-card import is used; you have no mean to understand how many classes are really used. As in: if your class needs 50, 100 imports ... that alone would tell you that something is wrong (because your class has way too many dependencies when it is importing 50, 100 other classes). If wildcards are used, you wouldn't know.
As a consequence, tools such as eclipse will by default "roll out" wildcard imports and turn them into specific class imports instead.
Lets be precise: using "import *" is never required. It just seems convenient at times! And when "import x.y.*" does not work; but "import x.y.z" works; then well, you must have done something wrong!

Related

Java how import order matters when import class/enum inner an inner class

Here is my class:
package pepelu;
import pepelu.ImportTest.InnerClass.InnerEnum;
import javax.annotation.Resource;
public class ImportTest {
#Resource
public static class InnerClass {
public enum InnerEnum {
A
}
}
public static void main(String[] args) {
System.out.println(InnerEnum.A);
}
}
When I use maven to build, it will give a compilation error:
mvn clean compile
[ERROR] /Users/finup/Desktop/a/importtest/src/main/java/pepelu/ImportTest.java:[8,6] cannot find symbol
After changing the import order to:
import javax.annotation.Resource;
import pepelu.ImportTest.InnerClass.InnerEnum;
I got a successful maven build.
I searched for documents, but cannot find an explain for this.
Could anyone please explain how import works in this case?
I guess the reason is a "circular" dependency: you have some element X that you import within the same file/class where you are defining it.
Meaning:
import pepelu.ImportTest.InnerClass.InnerEnum;
actually refers to code following in the very same file:
public static class InnerClass {
public enum InnerEnum {
This means: for the compiler, in order to process that import, it has to look into the body of the class in the same file.
It seems that javac does that "immediately". Meaning: it starts reading import statements, and importing from the same class makes it "suspend" looking at imports, but checking out the following class definition.
And guess what: that class definition makes use of another import. In order to "process" the definition of that enum, the compiler needs to understand where/what that #Resource annotation is about. But it doesn't know the annotation yet (because the compiler didn't see the import, yet).
When you change the order, the compiler understands that #Resource usage in the class definition.
And of course: the real answer is not to reorder imports. The real answer is to not import something from the class that is following after the import statements. There is absolutely no point in doing so.
Edit, given the comment by the OP about how this can work in Redisson: honestly, I don't know. It might depend on how exactly that class is compiled. Maybe such code works with newer (or older) versions of javac, maybe this works with specific versions of the eclipse or intellij or xyz compiler.
Meaning: I gave you an explanation why you are running into this problem. That doesn't mean that any compiler must necessarily run into the same problem.

How can I use import and inheritance together?

I have started learning Java and I tried to play with import and inheritance in netbeans IDE.
In netbeans I have created a project and two folders 'food' and 'food1'.
food has Fruit.java in it and food1 has Apple.java.
here's the code which is working fine.
Fruit.java
package food;
public abstract class Fruit{
}
Apple.java
package food1;
import food.Fruit;
class Apple extends Fruit{
}
Problem:
1. If i'm not declaring packages(package food and package food1) , it's not working. But i have already put them in the folders manually.
2. If i'm removing the import statement, it's not working. But the class fruit has been declared public.
Your Problem descriptions are correct - means, it works as expected:
If i'm not declaring packages(package food and package food1) , it's not working
Yes, the directory structure must be consistent with the package names. If your directory structure looks like
src
+--food
| +--Fruit.java
+--food1
+--Apple.java
then Fruit.java needs to have the package food statement and Apple.java needs to have the package food1 statement.
If i'm removing the import statement, it's not working. But the class fruit has been declared public.
Yes, if you want to use a class from a different package you must import it (or use a fully qualified class name which includes the package name, like ... extends food.Fruit - the usual approach is to import, though). Declaring the class public is not sufficient - it just defines the class can be used from outside the package, but you still need to import it.
See also
https://docs.oracle.com/javase/tutorial/java/package
http://www.studytonight.com/java/package-in-java.php

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?

Why don't I have to import a class I just made to use it in my main class? (Java)

I am currently learning Java using the Deitel's book Java How to Program 8th edition (early objects version).
I am on the chapter on creating classes and methods.
However, I got really confused by the example provided there because it consists of two separate .java files and when one of them uses a method from the other one, it did not import the class. It just created an object of that class from the other .java file without importing it first.
How does that work? Why don't I need to import it?
Here is the code from the book (I removed most comments, to save typing space/time...):
.java class:
//GradeBook.java
public class GradeBook
{
public void displayMessage()
{
System.out.printf( "Welcome to the grade book!" );
}
}
The main .java file:
//GradeBookTest.java
public class GradeBookTest
{
public static void main( String[] args)
{
GradeBook myGradeBook = new GradeBook();
myGradeBook.displayMessage();
}
}
I thought I had to write
import GradeBook.java;
or something like that.
How does the compiler know where GradeBook class and its methods are found and how does it know if it exists at all if we dont import that class?
I did lots of Googling but found no answer.
I am new to programming so please tolerate my newbie question.
Thank you in advance.
It is because both are in same package(folder). They are automatically imported no need to write import statement for that.
You don't have to import classes that are in the same package as the current class.
Also, note that GradeBook.java is the name of the file. The (simple) name of the class is GradeBook. Every class should be in a package. If it is in the package com.foo.bar, the class name is com.foo.bar.GradeBook, and this is the name you must use when importing this class.
Read http://download.oracle.com/javase/tutorial/java/package/packages.html to learn more about packages.
The classes located in the same package do not have to be imported, as they are visible to each other. You simply import a class that is in another package:
import java.util.ArrayList;
Note that you are not importing the file, but the class.
It's all about packages. You are trying to use a class from the default package which does not need explicit import of the java file, ie GradeBook inside GradeBookTest
Here is where you can start with learning about packages :
Java Package Tutorial
and :
Creating and Using Packages
Java doesn't use includes the way C does. Instead java uses a concept called the classpath, a list of resources containing java classes. The JVM can access any class on the classpath by name so if you can extend classes and refer to types simply by declaring them.
From: Include one java file in another java file
Imports are for importing classes that are in a different package. Since you didn't declare a package for either they are both put in the default package. The compiler can find it because the class lives in the same directory.
You don't have to import classes which are in the same package.
Well, classes in the same package are automatically imported.
They're in the same package. This tutorial will do more justice than I will.

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