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.
Related
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
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 wrote a method public static String timestamp() in a class called Utilities, which I want to call in every System.out.println().
Can you tell me how I can call this method in a different package? For example when I have package XY, with the class XY in it, then I can't call the timestamp() method, which is in the root src folder.
You need to use the whole class name, so as your class is called "Utilities":
Utilities.timestamp();
Will call your method. Remember to import your "Utilities" class at the top of your calling class.
Alternatively, if you want to just call:
timestamp();
You can statically import the class:
import static com.foo.Utilities
You need to import the package containing the class containing the timestamp() method. If you haven't declared a package for the class, you should do it now. After importing you can just use Utilities.timestamp() to call it.
If you're unfamiliar with packages in general, you should see the Oracle tutorials: http://docs.oracle.com/javase/tutorial/java/package/
So, more often than not, utility classes are declared as static. I'll give you an example.
Example
public class Utilities
{
public static String timestamp()
{
// Return timestamp.
}
}
Then in your XY class, you need to import your Utilities class, and you can access it as follows.
Utilities.timestamp();
You can call it using:
Utilities.timestamp();
from any class. Remember to import the Utilities class
It's static so you can just call Utilities.timestamp();
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.
class TestFormat
{
public static void main(String[] args)
{
System.out.println("hello");
}
}
In the above simple code the out object is of type java.io.PrintStream. The println() method is also of class PrintStream. PrintStream resides in a different package then java.lang which is the default java package.
My question is how are we able to use method of a class from a package(java.io) we have not even imported? Granted that the object of that class is already provided to us but does that means that we need to import a package only to create an object of a class from that package and not to use its methods afterwards?
Thnax in advance!
You misunderstand what import does.
Yes, you can use a class and its methods without an import statement. It means that you'll have to type out java.io.PrintStream instead of using the short name PrintStream.
The class loader searches the classpath for a .class file when you first use a class; import has nothing to do with this process. It's just a way to save you from having to type out the fully resolved class name.
You can write Java successfully and never use an import if you wish. You just need to be a good touch typist.
import is just saves you from typing total path if you import that class you are able to write PrintStream otherwise you have to write complete path java.io.PrintStream