Lets say , there are some import statements in a class. When the byte code is generated for that class, what happens to these import statements.
If the import statements are ignored during runtime, how are the dependencies on that classes methods resolved during runtime.
The purpose of import statements is just to make life easier for the human readers (and authors) of the code. Thus they are replaced by references to the fully qualified class/method names in the bytecode. And unused import statements are ignored.
import statements are only there for the compiler so it knows what class names (or static method names) you can access unqualified in your code (i.e. MyClass instead of foo.bar.MyClass). Behind the scenes this is just used to resolve to the fully-qualified class names which are then used in the bytecode as well.
import in Java is just a shorthand
so that if you import java.util.* you don't have to write java.util.ArrayList in your code but can write ArrayList
Related
I'm talking about the stuff we import.
Suppose, there is something like:
import java.util.Scanner;
util is the package and Scanner is the class, right?
Can this be always generalised and be said that in the import statement, the first one would be java/javax (is there any other?), the second one package, the third class and the fourth, if any, will always be a method belonging to the class?
Are there any exceptions, if so please name them.
Can this be always generalised and be said that in the import statement, the first one would be java/javax (is there any other?), the second one package, the third class and the fourth, if any will always be a method belonging to the class?
Not really, no.
The package is java.util, and you'll definitely see other packages, including the ones you write.
Within a normal import statement, there'll be a package, then either a specific class name or a * (to import all the classes in a package). But the class name could be a nested class name, so you could have:
import foo.bar.Outer.Nested;
where foo.bar is the package name, and Outer.Nested is the class name.
Then there are static imports, where you import members of classes, e.g.
import static java.lang.Math.sqrt;
See the Java tutorial on imports for more details.
No, it does not need to start with java, you can use anything as package name. Usually package names have a pattern like: com.someone.project.any.package.Class where com.someone represents the domain, project the project name and any.package your package hierarchy inside the project. This is just a convention but I would recommend you to use it.
Also take a look at: https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html
simple example from andEngine library:
org.andengine.entity.modifier.FadeOutModifier;
as you can see it has four nods. Last one is a class, extending modifier class, extending entity class, in package org.andengine... Also it does not start with java.
Hope it explains a bit
In your example
import java.util.Scanner;
java.util is the package, Scanner is the class you're importing from that package to be visible to the compiler.
See, for example, these lines from a the imports section of a pretty normal java file:
import java.util.Map;
import com.google.common.collect.ImmutableMap;
import org.apache.commons.lang.StringUtils;
These are all valid imports, which import the Map interface from java.util package, the ImmutableMap class from com.google.common.collect package, etc.
while preparing for the JCA exam I just came across this snippet
import java.lang.String.*;
class EJava
{
String guru;
}
This is of course nonsense code as java.lang is imported by default. Anyway, the author wants to use it to make the point that this code won't compile as it uses an incorrect import syntax.
The code does compile, though. So is it just the case that an import using a wildcard can simply mean two things?
import somepackage.*; // import any type in the package somepackage
import somepackage.type.*; // import any member of this type (equivalent to : import somepackege.type;)
This would definitely compile, but the statement will import all public nested classes in the java.lang.String class and unfortunately there are none.
So effectively the statement is useless yet harmless. There should be no problem in compilation.
If you were using static import, the case would have been different, as there are many static methods in String class.
From the Java Language Specification
A type-import-on-demand declaration allows all accessible types of a
named package or type to be imported as needed.
[...]
A static-import-on-demand declaration allows all accessible static
members of a named type to be imported as needed.
So your
import java.lang.String.*;
would import all accessible types in String (there are no accessible ones in Oracle JDK 8). A static import would import all accessible static members, including methods.
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.
I use a mass import class group as below:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.io.*;
import java.text.*;
import java.util.regex.*;
This way I don't have to worry about leaving any classes out.
Then when I used List I got this error:
reference to List is ambiguous, both class java.util.List in java.util
and class java.awt.List in java.awt match
How do I fix this? Is there a way to deport one of the classes? Which one is better?
You will need to refer to these types with their fully qualified names, java.util.List and java.awt.List, throughout this class file.
This will disambiguate the two Lists so that it won't strictly be necessary to "deport" anything (your import statements can stay the same). However I do agree with the other answer's recommendations that you tidy up your imports.
If one of the Lists was "deported" then that would let you refer to the other List by its short name.
Firstly, you shouldn't import whole packages like that. You should include only what is required. IDEs do have options where they will include for you whatever is required. At least Eclipse does that. For reading its disadvantages in detail you can go through the following link:
Any difference between class imports and package imports in Java?
However, if it is absolutely necessary then ambiguity can be avoided by referring to these ambiguous classes with their fully qualified names e.g., in your case
java.util.List AND/OR java.awt.List
The fix is to not import everything like that. Use an IDE like Eclipse to manage your imports for you.
always and always import only the classes that you use in your particular program. For classes with the same name but different package like the List class that you are using, can be specified with their fully qualified names rather than the import statement
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().