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.
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 was reading about predefined methods and was learning about import statements. I have seen and often times used these to use certain predefined methods, but I've always seen them placed at the very beginning of a program. My question is, can these be placed inside a certain block of code so that it is only seen in that block? I'm not sure that there would ever actually be a reason for this, mostly just curious.
java files contains three parts:
package definition
imports definitions (optional)
the class (or interface/enum) definition.
and it also has to be in this order, you'll get compilation error if it's not in this order
No, you need to define it before of the class/interface, after the package statement.
So an import is always visible to the entire .class-file.
import lets you use members of other packages than your local package, without specifying the full name of a class (e.g. either you need to import java.util.List, or you need to use it's full name everywhere).
There is a tutorial on using package members by Oracle.
The order in a .class-file is defined as:
package specification (optional)
import statements
class / interface / enum definition
My guess is that will give you a compiler error. BUT you can effectively acheive the same thing if you specify the full package name of a class when you instantiate it.
E.g:
public String getString() {
return new com.package.some.Class("hello world").toString();
}
In this case you don't need to have an 'import' directive at the top of the class because you are telling the compiler inside the method that the class you want is located in the com.package.some package and the class is called Class.
This actually happens in the wild when for example you have to classes in different packages that have the same name. You can only import one of them, the other one you will have to inline the package definition inside the code.
import com.package.some.Class;
public class Yolo {
private Class classA;
private com.package.other.Class classB;
public Yolo(Class classA, com.package.other.Class classB) {
this.classA = classA;
this.classB = classB;
}
}
you can't just import both 'Class' objects and refer to them as Class because the compiler won't know which one. So, this is a valid situation where you will see this kind of thing happen for real.
From Oracle Docs :
Importing a Package Member
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. Here's how you would
import the Rectangle class from the graphics package created in the
previous section.
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.
I'm studying for a beginners Java Exam through Oracle.
One of the questions says given:
int absoluteValue = abs(-21)
What import statement will compile all the code?
Correct answer given as:
import static java.lang.Math.abs;
But my question is if java.lang.* is imported by default then why is the Math class not imported and the abs() method not available?
But my question is if java.lang.* is imported by default then why is the Math class not imported and the abs method not available?
Because it isn't.
Because that is the way that Java works. An implicit (or explicit) wildcard import of the classes in a package only imports the classes. It doesn't also do a static import of class members.
If you want to refer to all static members of a class without qualifying them, you should use a wildcard static import; e.g.
import static java.lang.Math.*;
Alternatively you can static import individual members; e.g.
import static java.lang.Math.abs;
Why did they define Java this way?
Well it is most likely rationale is that implicit importing makes it harder to read code. If methods like abs get imported by default, then you need to know what they all are ... and where they are imported from ... in order to understand the true meaning of the code.
It is worth knowing that static imports were only added in Java 5. Prior to that, it was not possible to refer to Math.abs without the Math qualification.
If you just import the class not its static members then what are you getting when you import it?
You just get the class name. For example:
import java.util.HashMap;
allows me to write new HashMap() rather than new java.util.HashMap() etcetera. This is significant. (Imagine if you always had to refer to classes by their full name ....)
you have to call abs() method on class name of math class Math.abs(), It is static method.
or you have to import import static java.lang.Math.abs;
Internal Implementation of Math class absolute() method.
public static long abs(long a) {
return (a < 0) ? -a : a;
}
abs() method is static method, java.lang.*; can not import static member of class.
Java doesn't allow static method to be imported by default. All methods in java.lang.Math class are static. That's why these method are not imported by default where all classes from java.lang.* package is imported by default.
In addition to import static java.lang.Math.abs; - this statement you can use the either of following two -
Math.abs() to directly (without any import statement) call the abs() method. But this only works for the static method in java.lang package, since they are imported by default.
Or using the following import statement -
import static java.lang.Math.*;
In this case you can use the abs() method without the class name - Math. This technique (static import) will work for all static method of any class under any package.
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.