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.
Related
In Java Documentation I found that naming convention of a package should be like this:
Package names are written in all lower case to avoid conflict with the
names of classes or interfaces.
But I have seen lots of Classes in Java and Android like below:
import java.util.HashMap;
import androidx.core.content.ContextCompat;
import android.view.inputmethod.InputMethodManager;
What is the standard here? Are these examples are a deviation from the conventions?
That's because
import java.util.HashMap;
Hashmap refers to the class, not the package.
It reads that :
Hashmap is a class found within the package of java.util
Here's the actual package and class in question:
Import statements consist of two parts, the package name and the actual class which resides in the package. For example, your import:
import java.util.HashMap;
Actually says to import the HashMap class which resides in the java.util package. In fact, the package name does consist only of lowercase letters. But, the class is in upper camelcase, as is also the convention.
You are confusing
import some.package.with.WhatEverClass
with
import some.package.with.*
In other words: the upper case comes in because the last part of the import statement refers to a class, not a package.
This is similar to what you can do in python:
import re
will import the whole module, whereas that first java example is more like
from foo import bar
You are right package name in java are written in lowercase. However,
examples given in question are of import not package.
Package in HashMap class would be like this package java.util;
And java.util.HashMap is fully qualified class name. Fully qualified class name(class name with package) are used in import.
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 am a newbie to Java development. I have a quick question regarding recursive imports in Java.
Lets assume Package "pkg" contains the following
class A,
package B (This in turn contains B1 class)
package C (This in turn contains C1 class)
If I use import pkg.* why am I not allowed to import classes from packages "B" and "C" ?.
I would like to understand the rationale behind in Java's not allowing me to do recursive imports.
Your question is poorly phrased, because if you import pkg.*, you certainly are allowed to then import classes from packages pkg.B and pkg.C. That is, it is perfectly fine to do this:
import pkg.*;
import pkg.B.*;
import pkg.C.*;
But I assume that what you really are asking is why, if you import pkg.* it does not automatically import the types declared in the subpackages of pkg. To answer that, it's best to turn to the Java Language Specification:
The hierarchical naming structure for packages is intended to be convenient for organizing related packages in a conventional manner, but has no significance in itself other than the prohibition against a package having a subpackage with the same simple name as a top level type (§7.6) declared in that package.
For example, there is no special access relationship between a package named oliver and another package named oliver.twist, or between packages named evelyn.wood and evelyn.waugh. That is, the code in a package named oliver.twist has no better access to the types declared within package oliver than code in any other package.
In other words, when you import pkg.*, you are importing all the top-level types defined by the compilation units contained in the package named pkg, but you are not importing any of the sub-packages of pkg (such as pkg.B or pkg.C).
It sounds like you're asking why import java.awt.* doesn't also import java.awt.color.* and so on.
This is best explained by this tutorial where it says
At first, packages appear to be hierarchical, but they are not. For
example, the Java API includes a java.awt package, a java.awt.color
package, a java.awt.font package, and many others that begin with
java.awt. However, the java.awt.color package, the java.awt.font
package, and other java.awt.xxxx packages are not included in the
java.awt package. The prefix java.awt (the Java Abstract Window
Toolkit) is used for a number of related packages to make the
relationship evident, but not to show inclusion.
More importantly,
Importing java.awt.* imports all of the types in the java.awt package,
but it does not import java.awt.color, java.awt.font, or any other
java.awt.xxxx packages. If you plan to use the classes and other types
in java.awt.color as well as those in java.awt, you must import both
packages with all their files:
import java.awt.*;
import java.awt.color.*;
The convention in Java is to import only the classes you required. Most IDEs will automatically organise them for you. Importing classes in bulk is not common like in other languages.
There is no restriction on imports as you described in your original question (prior to the edit).
Let's assume you have the following Hierarchy:
pkg1
A.java
pkg1.pkg2
B.java
pkg1.pkg3
C.java
D.java
You are permitted to import any of the A.java, B.java, C.java, D.java, or combinations therein.
import pkg1.A;
import pkg1.pkg2.B;
import pkg1.pkg3.C;
import pkg1.pkg3.D;
The only caveat is that within class C, you can use class D without importing D explicitly because they share the same package.
However, a blanket statement like import pkg1.* will not pull in the classes located further down the package hierarchy; you'd need to import each sub-package as well: import pkg1.pkg2.*, etc. This is simply how the language is designed.
I'm reading every tutorial I can find as well as a book, still trivial concetps leave me asking questions:
CLASSPATH is a variable registered with the JVM that tells java the root directory in which to start looking for classes/jars/etc?
import is similar to include (C/C++) but provides a namespace via package? I just read how without using import you have to explicitly state the package/namespace for every class (using the FQCN) such as java.util.String (possibly invalid excuse) where as using import java.util would allow me everywhere else in the code to simply refer to class as String.
What confuses me about import is some examples use import like:
import java.util.*; // import all public classes from java.util package
import java.util.Hashtable; // import only Hashtable class (not all classes in java.util package)
Yes the article also follows up:
Note that we can call public classes stored in the package level we do the import only. We can't use any classes that belong to the subpackage of the package we import. For example, if we import package world, we can use only the HelloWorld class, but not the HelloMoon class.
So which is it, when I use the * in an import is that not recursively importing all sub-packages?
7.5.2. Type-Import-on-Demand Declarations
import java.util.*;
causes the simple names of all public types declared in the package java.util to be available within the class and interface declarations of the compilation unit. Thus, the simple name Vector refers to the type Vector in the package java.util in all places in the compilation unit where that type declaration is not shadowed (§6.4.1) or obscured (§6.4.2).
The declaration might be shadowed by a single-type-import declaration of a type whose simple name is Vector; by a type named Vector and declared in the package to which the compilation unit belongs; or any nested classes or interfaces.
The declaration might be obscured by a declaration of a field, parameter, or local variable named Vector.
(It would be unusual for any of these conditions to occur.)
You are correct.
Unlike C/C++ include, Java's import is optional, as Java loads all classes it finds in CLASSPATH regardless.
Java's import statements allows you to alias commonly used classes so you don't have to fully qualify them each time.
Let's say you have the following class defined:
package com.foo.bar;
public class Bazz {
public static final int ONE = 1;
public static final int TWO = 2;
public static final int THREE = 3;
... some methods ...
}
There are several ways of using import:
import com.foo.bar.*; // import all classes belonging to package com.foo.bar, and com.foo.bar only.
import com.foo.bar.Bazz; // import class com.foo.bar.Bazz only
import static com.foo.bar.Bazz.*; // import all static constants in class com.foo.bar.Bazz
import static com.foo.bar.Bazz.ONE; // import static constant com.foo.bar.Bazz.ONE only
As you state, there is no way of recursively importing packages.
As an aside, most IDEs will auto-import the classes for you. For example, Eclipse does this when you press CTRL+SHIFT+O.
As in the example you provided in the question, when you specify
import java.util.*;
You import all of the public classes in the java.util package. You do not import any public classes that reside outside the java.util package.
Integrated development environments (IDE) like Eclipse will create individual class imports for you. There's not much reason to code a global import (with an asterisk) any more.
Yes. That's what it does.
But it is best practice to provide absolute path in the import statement.
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