Java : Accessing a class within a package, which is the better way? - java

If I access a class within a package using fully qualified name, without importing it, whether it saves any memory?
Using fully qualified class name :
java.lang.Math.sqrt(x);
Import package :
import java.lang.Math;
Math.sqrt(x);
which is the better way : import the package or access using fully qualified name?
Thanking you..

There is no performance difference between importing the package or using the fully qualified class name. The import directive is not converted to Java byte code, consequently there is no effect on runtime performance. The only difference is that it saves you time in case you are using the imported class multiple times. This is a good read here

No, it doesn't save you memory.
Also note that you don't have to import Math at all. Everything in java.lang is imported automatically.
A better example would be something like an ArrayList
import java.util.ArrayList;
....
ArrayList<String> i = new ArrayList<String>();
Note I'm importing the ArrayList specifically. I could have done
import java.util.*;
But you generally want to avoid large wildcard imports to avoid the problem of collisions between packages.

They're equivalent. The access is the same.
The import is just a convention to save you from having to type the fully-resolved class name each time. You can write all your Java without using import, as long as you're a fast touch typer.
But there's no difference in efficiency or class loading.

As already said, on runtime there is no difference (in the class file it is always fully qualified, and after loading and linking the class there are direct pointers to the referred method), and everything in the java.lang package is automatically imported, as is everything in the current package.
The compiler might have to search some microseconds longer, but this should not be a reason - decide for legibility for human readers.
By the way, if you are using lots of static methods (from Math, for example), you could also write
import static java.lang.Math.*;
and then use
sqrt(x)
directly. But only do this if your class is math heavy and it really helps legibility of bigger formulas, since the reader (as the compiler) first would search in the same class and maybe in superclasses, too. (This applies analogously for other static methods and static variables (or constants), too.)

Import package is for better readability;
Fully qualified class has to be used in special scenarios. For example, same class name in different package, or use reflect such as Class.forName().

Related

Why does importing a class not import all of its dependencies?

If I want to use an ArrayList in my code, I need to import java.util.ArrayList. If I also want to use a List, I have to import java.util.List. Why is this needed? ArrayList inherits from List, and thus uses code from it. Why does that not carry over to my class? Surely if ArrayList imports List, and my class in turn imports ArrayList, then List should be defined in my class?
import is just a syntactic feature that lets you avoid writing out the full package every time you use a classname.
You do not need to import dependencies at all.
Some classes depend on a lot of classes and those classes depend on a lot of classes, and you would end up importing a good portion on the JDK. It can't assume which classes/interface you might want to import as well.
If you use an IDE, it can add the imports for you so you don't have to worry about which ones are needed most of the time.
The import keyword does not actually "import" anything: it just tells the compiler that you would like to refer to something by its short name. This is why the "import List" in the ArrayList class has no effect on your class.
You can import everything from a particular package like so: java.util.*;
Keep in mind though, that there is a particular annoyance when doing so, as you need to fully qualify other objects that may share the same class name with the imported package. Check this for reference:
Why is using a wild card with a Java import statement bad?
This is a clear instance of "declare what is being used". You might consider is a distant variant of "need to know".
Using an "ArrayList" does not require you to use "List" also.
If, however, you want to use a "java.util.List" (e,g, as the type of a variable being initialized with an instance of "ArrayList"),
then you clearly should state that you are using both types.
(Or actually , just disambiguate what is intended to be referred to by the simple names used, like "List".)
Why clutter your import section with any possible parent type and interface from any class you are using (even if done implicitly)?
Would likely not provide too much benefit, while at the same time
it would make live harder in case you reall want to use a different class with the same name (other package).
Of course you might remember that you are not required to use "imports" at all. You will need to use full names of classes then,
but it is completely valid to do so.
Furthermore, most modern IDEs will suggest a proper import when using a simple name based on what is also used in the expression context. (So e.g. if you use "List" as a variable type when assigning from an "ArrayList" might suggest "java.util.List" as resulution for "List" with higher priority than other clases named "List".
I completely agree with your question. It would be a lot easier to write code if we do not have to worry about keeping track of long list of import statements.
But, the way java (compiler and runtime) works, I think it is necessary to do so because of the following.
The import statements in Java are only for a compiler. The runtime doesn't know anything about import statements.
When you compile your code, all the class names that you use gets converted into fully qualified classnames by the compiler. If we explicitly do not mention which class we are referring to, compiler might get confused if there are multiple classes matching with the same class name that you provided.
You could say that, java should atleast import non-duplicate classes automatically. But the problem is you never know which classes are non duplicate.
Anyone can create a class with any name (I can even create a class in my own package with name ArrayList or List). For that reason, compiler need to know beforehand if it has to resolve List to java.util.List or some other List.
Yes and no. An ArrayList object will indeed have access to any property (method, object...) defined in the class it extends/implements. But, the class you are working in doesn't know about such super classes. You have to import them explicitly to reference them. You could of course import java.util.* and that will give your class access to all classes in that package.

Can import statements be used anywhere besides the beginning of a Java file?

In python, the import statement can be placed everywhere in the file, even inside a class, or an if.
Is there a way to accomplish the same thing in Java? I understand that it could be a bad practice not to put all the imports at the top of the file, I'm just wondering if it is possible in some way or not.
The very first statement in a Java file must be (if there is one) the package statement, followed by the import statements. They can not be placed in another location.
However, it is possible to skip the import altogether by using fully qualified class names (which I personally don't recommend). You need to use them everywhere you would have used the short, unqualified name.
import my.package.MyClass;
public class Test{
private MyClass instance = new MyClass();
}
can be rewritten as:
public class Test{
private my.package.MyClass instance = new my.package.MyClass();
}
According to the documentation here:
To import a specific member into the current file, put an import statement at the beginning of the file before any type definitions but after the package statement, if there is one.
So it seems that it is not possible.
Short answer : No it's impossible !
The import statement must be in the top of the file after the package statement (if exist).
You must know : You can use your imported class/interface or static method in all classes/interfaces in the same file including inner/nested classes.
There isn't a way, except maybe messing with bytecode if you count that. I suppose the best equivalent would be writing the fully qualified name of what you're looking to use.
Not sure why you would want to though.
No. They need to be at the top, after the package declaration.
An ordinary compilation unit consists of three parts, each of which is
optional:
A package declaration (§7.4), giving the fully qualified name (§6.7) of the package to which the compilation unit belongs.A compilation unit that has no package declaration is part of an
unnamed package (§7.4.2).
import declarations (§7.5) that allow classes and interface from other packages, and static members of classes and interfaces, to be
referred to using their simple names.
Top level declarations of classes and interfaces (§7.6).
This doesn't do a great job at conveying that the ordering of each part is strictly enforced, but the formal grammar does make this clear:
OrdinaryCompilationUnit:
[PackageDeclaration] {ImportDeclaration} {TopLevelClassOrInterfaceDeclaration}

Why did my import fail in Java?

I hava a StdDraw.java under the same folder of my working file, and picture() is a method within StdDraw.java.
However, I failed adding this line to import the method, suggesting by
package StdDraw does not exist
import StdDraw.picture
How could I possibly do that? Using package? Setting path? Or any modifications? I came from python and find it a little bit weird.
You can't import non-static methods (only classes and static members), and you don't have to!
If both your classes live in the default package then you should be able to do the following without any import statements :
myStdDrawObject.picture(); // if picture is non-static
or
StdDraw.picture(); // if picture is static
Note also, that you can't use static imports on classes that live in the default package.
If you are importing into the class which is there in same package then we no need to use any import.
if you want import mthods into the class use like below. You no need to put method name at the time of the import.
import packagename.StdDraw;
After importing your class, all non static methods of the class are available into the imported class.
when should you use static import? Only use it when you'd otherwise be
tempted to declare local copies of constants, or to abuse inheritance
(the Constant Interface Antipattern). In other words, use it when you
require frequent access to static members from one or two classes. If
you overuse the static import feature, it can make your program
unreadable and unmaintainable, polluting its namespace with all the
static members you import. Readers of your code (including you, a few
months after you wrote it) will not know which class a static member
comes from. Importing all of the static members from a class can be
particularly harmful to readability; if you need only one or two
members, import them individually. Used appropriately, static import
can make your program more readable, by removing the boilerplate of
repetition of class
names.
Read more about static import:
https://docs.oracle.com/javase/1.5.0/docs/guide/language/static-import.html
When importing the package you do not need to import non static methods. You can read on Java - Packages here. It is easily explained and I found it useful when learning the same concept.
Even if you do not include import for the class which is present in the same folder, then also you can create object and call method of that class and also static methods.
You can create object and call the non-static methods.
StdDraw drawObj = new StdDraw();
drawObj.picture(); // if picture is non-static method
For static method, you can call it using class name only.
StdDraw.picture(); // if picture is static method.
What I recommend is to read up on packages and how code is organized in java. It is in someway similar to python, where a directory structure is used, but more to it in java. Maybe this will help
Java Tutorial- Packages

Java import all from all

I have a logical question: Why i cannot import all packages from all packages in java?
For example i can import all classes from java.awt:
import java.awt.*;
But the following isnt possible:
import java.awt.*.*;
My aim would be to import all stuff from awt.image and awt.event and so on.
Is there another way to do this?
Thank you!
There is no way to achieve an import a.package.*.*; in Java. The JLS, Section 7.5 specifies the only 4 types of imports that are legal:
A single-type-import declaration (§7.5.1) imports a single named type,
by mentioning its canonical name (§6.7).
e.g. import java.util.List;
A type-import-on-demand declaration (§7.5.2) imports all the
accessible types (§6.6) of a named type or named package as needed, by
mentioning the canonical name of a type or package.
e.g. import java.awt.*;
A single-static-import declaration (§7.5.3) imports all accessible
static members with a given name from a type, by giving its canonical
name.
e.g. import static org.junit.Assert.assertEquals;
A static-import-on-demand declaration (§7.5.4) imports all accessible
static members of a named type as needed, by mentioning the canonical
name of a type.
e.g. import static org.junit.Assert.*;
Packages allow classes of the same name to be referenced individually. E.g. there is java.awt.List and java.util.List. What would stop someone from importing everything with java.*.*;. How would List be resolved then? There would be too much ambiguity.
No, and using wildcard imports is bad style in general as it makes your code harder to read.
Some disadvantages of using wildcards imports:
Results in including classes that you might not use at all. Not clear picture of what you are working with.
More broader scope which is considered bad programming practice.
Most important can result in namespace clash. If you are blatantly importing everything from two packages it may result in clash between two classes with same name from different packages.
Edit: Seems like importing more classes than required doesn't result in any bulky code, but I would still prefer to import the classes explicitly to have a clear idea about what I am working with.

Java: Use import or explicit package / class name?

I'm writing a very basic app, extending the Swing JFrame. What are the differences between making an explicit reference:
public class LineTest extends javax.swing.JFrame {
...
or importing the class beforehand:
import javax.swing.JFrame;
public class LineTest extends JFrame {
...
When (and why) would you use one technique over the other?
There is no real difference; the generated byte code will be exactly the same. An import statement is really just a way to tell the compiler "when I write JFrame, I actually mean javax.swing.JFrame".
You might want to use fully-qualified package names if you have for example two classes with the same name in different packages. One common example from the standard library are the classes java.util.Date and java.sql.Date.
The only difference is in the source code. Using the fully qualified name leads to less readable code, so everyone uses imports pretty much exclusively. The only place where I've ever seen the fully qualified names used consistently is in generated code.
The only reason to use the fully qualified name in regular code is when you have to use two classes with the same simple name (e.g. java.util.List and java.awt.List) - in that case there is no alternative.
For the compiler it doesn't make any difference. The disadvantage of using the full qualified name is that you would have to write it each time you are using the class. I only use the full qualified name if I have two classes with the same name in different packages. This way you can differ between those two classes

Categories