Reflection API
Reflection API
Topics
1. Class Loader
2. Object class
3. == operator & .equals() (of String class) difference
4. Class
5. new & newInstance() difference
6. instanceof & isInstance difference
Class Loader
Reference:
https://www.geeksforgeeks.org/classloader-in-java/ (ClassLoader)
https://www.baeldung.com/java-classloaders (ClassLoader)
https://docs.oracle.com/javase/8/docs/technotes/tools/findingclasses.html (How Java launcher finds
classes)
https://docs.oracle.com/javase/tutorial/ext/basics/install.html (extension directory jdk/jre/lib/ext)
ClassLoader in Java
The Java ClassLoader is a part of the Java Runtime Environment that dynamically loads Java
classes into the Java Virtual Machine. The Java run time system does not need to know about
files and file systems because of classloaders. Java classes aren’t loaded into memory all at once,
but when required by an application. At this point, the Java ClassLoader is called by
the JRE and these ClassLoaders load classes into memory dynamically.
1. Delegation Model: The Java Virtual Machine and the Java ClassLoader use an algorithm
called the Delegation Hierarchy Algorithm to Load the classes into the Java file.
The ClassLoader works based on a set of operations given by the delegation model. They
are:
ClassLoader always follows the Delegation Hierarchy Principle.
Whenever JVM comes across a class, it checks whether that class is already loaded or
not.
If the Class is already loaded in the method area then the JVM proceeds with execution.
If the class is not present in the method area then the JVM asks the Java ClassLoader
Sub-System to load that particular class, then ClassLoader sub-system hands over the
control to Application ClassLoader.
Application ClassLoader then delegates the request to Extension ClassLoader and
the Extension ClassLoader in turn delegates the request to Bootstrap ClassLoader.
Bootstrap ClassLoader will search in the Bootstrap classpath (JDK/JRE/LIB). If the
class is available then it is loaded, if not the request is delegated to Extension
ClassLoader.
Extension ClassLoader searches for the class in the Extension Classpath
(JDK/JRE/LIB/EXT). If the class is available then it is loaded, if not the request is
delegated to the Application ClassLoader.
Application ClassLoader searches for the class in the Application Classpath. If the class
is available then it is loaded, if not then a ClassNotFoundException exception is
generated.
2. Visibility Principle: The Visibility Principle states that a class loaded by a parent
ClassLoader is visible to the child ClassLoaders but a class loaded by a child ClassLoader is
not visible to the parent ClassLoaders. Suppose a class GEEKS.class has been loaded by the
Extension ClassLoader, then that class is only visible to the Extension ClassLoader and
Application ClassLoader but not to the Bootstrap ClassLoader. If that class is again tried to
load using Bootstrap ClassLoader it gives an exception
java.lang.ClassNotFoundException.
3. Uniqueness Property: The Uniquesness Property ensures that the classes are unique and
there is no repetition of classes. This also ensures that the classes loaded by parent
classloaders are not loaded by the child classloaders. If the parent class loader isn’t able to
find the class, only then the current instance would attempt to do so itself.
Let's start by learning how different classes are loaded using various class loaders using a simple
example:
As we can see, there are three different class loaders here; application, extension, and bootstrap
(displayed as null).
The application class loader loads the class where the example method is contained. An
application or system class loader loads our own files in the classpath.
Next, the extension one loads the Logging class. Extension class loaders load classes that are
an extension of the standard core Java classes.
Finally, the bootstrap one loads the ArrayList class. A bootstrap or primordial class loader is
the parent of all the others.
However, we can see that the last out, for the ArrayList it displays null in the output. This is
because the bootstrap class loader is written in native code, not Java – so it doesn't show up
as a Java class. Due to this reason, the behavior of the bootstrap class loader will differ across
JVMs.
Let's now discuss more in detail about each of these class loaders.
Methods of Java.lang.ClassLoader
After the JVM requests for the class, a few steps are to be followed in order to load a class. The
Classes are loaded as per the delegation model but there are a few important Methods or
Functions that play a vital role in loading a Class.
1. loadClass(String name, boolean resolve): This method is used to load the classes which
are referenced by the JVM. It takes the name of the class as a parameter. This is of type
loadClass(String, boolean).
2. defineClass(): The defineClass() method is a final method and cannot be overriden. This
method is used to define an array of bytes as an instance of class. If the class is invalid then
it throws ClassFormatError.
3. findClass(String name): This method is used to find a specified class. This method only
finds but doesn’t load the class.
4. findLoadedClass(String name): This method is used to verify whether the Class referenced
by the JVM was previously loaded or not.
5. Class.forName(String name, boolean initialize, ClassLoader loader): This method is
used to load the class as well as initialize the class. This method also gives the option to
choose any one of the ClassLoaders. If the ClassLoader parameter is NULL then
Bootstrap ClassLoader is used.
Bootstrap classes - Classes that comprise the Java platform, including the classes in rt.jar and
several other important jar files.
Extension classes - Classes that use the Java Extension mechanism. These are bundled
as .jar files located in the extensions directory.
User classes - Classes defined by developers and third parties that do not take advantage of
the extension mechanism. You identify the location of these classes using the -
classpath option on the command line (the preferred method) or by using the CLASSPATH
environment variable. (See Setting the Classpath for Windows or Unix.)
In effect, these three search paths are joined to form a simple class path. This is similar to the
"flat" class path previously used, but the current model has some important differences:
It is very unlikely that you will need to redefine the bootstrap class path. The nonstandard
option, -Xbootclasspath, allows you to do so in those rare cicrcumstances in which it is
necessary to use a different set of core classes.
Note that the classes which implement the Java 2 SDK tools are in a separate archive from the
bootstrap classes. The tools archive is the SDK's/lib/tools.jar file. The development tools add this
archive to the user class path when invoking the launcher. However, this augmented user class
path is only used to execute the tool. The tools that process source code, javac and javadoc, use
the original class path, not the augmented version. (For more information, see How Javac and
Javadoc Find Classes, below.)
How the Java Launcher Finds Extension Classes
Extension classes are classes which extend the Java platform. Every .jar file in the extension
directory, jre/lib/ext, is assumed to be an extension and is loaded using the Java Extension
Framework. Loose class files in the extension directory will not be found. They must be
contained in a .jar file (or .zip file). There is no option provided for changing the location of the
extension directory.
If the jre/lib/ext directory contains multiple .jar files, and those files contain classes with the
same name, such as:
A class file has a subpath name that reflects the class's fully-qualified name. For example, if the
class com.mypackage.MyClass is stored under /myclasses, then /myclasses must be in the user
class path and the full path to the class file must be /myclasses/com/mypackage/MyClass.class. If
the class is stored in an archive named myclasses.jar, then myclasses.jar must be in the user class
path, and the class file must be stored in the archive as com/mypackage/MyClass.class.
The user class path is specified as a string, with a colon (:) separating the class path entries on
Solaris, and a semi-colon (;) separating entries on Microsoft Windows systems.
The java launcher puts the user class path string in the java.class.path system property. The
possible sources of this value are:
The default value, ".", meaning that user class files are all the class files in the current
directory (or under it, if in a package).
The value of the CLASSPATH environment variable, which overrides the default value.
The value of the -cp or -classpath command line option, which overrides both the default
value and the CLASSPATH value.
The JAR archive specified by the -jar option, which overrides all other values. If this option
is used, all user classes must come from the specified archive.
Installed Extensions
Installed extensions are JAR files in the lib/ext directory of the Java Runtime Environment
(JRE™) software. As its name implies, the JRE is the runtime portion of the Java Development
Kit containing the platform's core API but without development tools such as compilers and
debuggers. The JRE is available either by itself or as part of the Java Development Kit.
The JRE is a strict subset of the JDK software. A subset of the JDK software directory tree looks
like this:
The JRE consists of those directories within the highlighted box in the diagram. Whether your
JRE is stand-alone or part of the JDK software, any JAR file in the lib/ext of the JRE directory is
automatically treated by the runtime environment as an extension.
Since installed extensions extend the platform's core API, use them judiciously. They are rarely
appropriate for interfaces used by a single, or small set of applications.
Furthermore, since the symbols defined by installed extensions will be visible in all Java
processes, care should be taken to ensure that all visible symbols follow the appropriate "reverse
domain name" and "class hierarchy" conventions. For example, com.mycompany.MyClass.
As of Java 6, extension JAR files may also be placed in a location that is independent of any
particular JRE, so that extensions can be shared by all JREs that are installed on a system. Prior
to Java 6, the value of java.ext.dirs referred to a single directory, but as of Java 6 it is a list of
directories (like CLASSPATH) that specifies the locations in which extensions are searched for.
The first element of the path is always the lib/ext directory of the JRE. The second element is a
directory outside of the JRE. This other location allows extension JAR files to be installed once
and used by several JREs installed on that system. The location varies depending on the
operating system:
Note that an installed extension placed in one of the above directories extends the platform
of each of the JREs (Java 6 or later) on that system.
A Simple Example
Let's create a simple installed extension. Our extension consists of one class, RectangleArea, that
computes the areas of rectangles:
This class has a single method, area, that takes an instance of java.awt.Rectangle and returns the
rectangle's area.
Suppose that you want to test RectangleArea with an application called AreaApp:
import java.awt.*;
Let's first review how you would run the AreaApp application without using the extension
mechanism. We'll assume that the RectangleArea class is bundled in a JAR file named area.jar.
The RectangleArea class is not part of the Java platform, of course, so you would need to place
the area.jar file on the class path in order to run AreaApp without getting a runtime exception.
If area.jar was in the directory /home/user, for example, you could use this command:
The class path specified in this command contains both the current directory,
containing AreaApp.class, and the path to the JAR file containing the RectangleArea package.
You would get the desired output by running this command:
Now let's look at how you would run AreaApp by using the RectangleArea class as an extension.
To make the RectangleArea class into an extension, you place the file area.jar in
the lib/ext directory of the JRE. Doing so automatically gives the RectangleArea the status of
being an installed extension.
With area.jar installed as an extension, you can run AreaApp without needing to specify the class
path:
java AreaApp
Because you're using area.jar as an installed extension, the runtime environment will be able to
find and to load the RectangleArea class even though you haven't specified it on the class path.
Similarly, any applet or application being run by any user on your system would be able to find
and use the RectangleArea class.
If there are multiple JREs (Java 6 or later) installed on a system and want
the RectangleArea class to be available as an extension to all of them, instead of installing it in
the lib/ext directory of a particular JRE, install it in the system-wide location. For example, on
system running Linux, install area.jar in the directory /usr/java/packages/lib/ext.
Then AreaApp can run using different JREs that are installed on that system, for example if
different browsers are configured to use different JREs.
Object (java.lang.Object)
Reference:
https://www.geeksforgeeks.org/object-class-in-java/
toString() : toString() provides String representation of an Object and used to convert an object
to String. The default toString() method for class Object returns a string consisting of the name
of the class of which the object is an instance, the at-sign character `@’, and the unsigned
hexadecimal representation of the hash code of the object. In other words, it is defined as:
// Default behavior of toString() is to print class name, then @, then unsigned hexadecimal
representation of the hash code of the object
It is always recommended to override toString() method to get our own String representation of
Object. For more on override of toString() method refer – Overriding toString() in Java
Note: Whenever we try to print any Object reference, then internally toString() method is
called.
hashCode() : For every object, JVM generates a unique number which is hashcode. It returns
distinct integers for distinct objects. A common misconception about this method is that
hashCode() method returns the address of object, which is not correct. It convert the internal
address of object to an integer by using an algorithm. The hashCode() method is native because
in Java it is impossible to find address of an object, so it uses native languages like C/C++ to find
address of the object.
Use of hashCode() method : Returns a hash value that is used to search object in a collection.
JVM(Java Virtual Machine) uses hashcode method while saving objects into hashing related data
structures like HashSet, HashMap, Hashtable etc. The main advantage of saving objects based on
hash code is that searching becomes easy.
Note: Override of hashCode() method needs to be done such that for every object we generate a
unique number. For example, for a Student class we can return roll no. of student from
hashCode() method as it is unique.
// Constructor
Student()
{
roll_no = last_roll;
last_roll++;
}
// Overriding hashCode()
@Override
public int hashCode()
{
return roll_no;
}
// Driver code
public static void main(String args[])
{
Student s = new Student();
equals(Object obj) : Compares the given object to “this” object (the object on which the method
is called). It gives a generic way to compare objects for equality. It is recommended to
override equals(Object obj) method to get our own equality condition on Objects.
Note : It is generally necessary to override the hashCode() method whenever this method is
overridden, so as to maintain the general contract for the hashCode method, which states that
equal objects must have equal hash codes.
https://www.javatpoint.com/java-object-equals-method
equals(Object obj) is the method of Object class. This method is used to compare the given
objects. It is suggested to override equals(Object obj) method to get our own equality condition
on Objects.
Syntax
public boolean equals(Object obj)
Parameter
obj - it is the reference object.
Returns
It returns true if this object is same as the obj argument else it returns false otherwise.
Example 1
public class JavaObjectequalsExample1 {
static int a = 10, b=20;
int c;
// Constructor
JavaObjectequalsExample1()
{
System.out.println("Addition of 10 and 20 : ");
c=a+b;
System.out.println("Answer : "+c);
}
// Driver code
public static void main(String args[])
{
System.out.println("1st object created...");
JavaObjectequalsExample1 obj1 = new JavaObjectequalsExample1();
System.out.println("2nd object created...");
JavaObjectequalsExample1 obj2 = new JavaObjectequalsExample1();
System.out.println("Objects are equal:" + obj1.equals(obj2));
}
}
Output:
1st object created...
Addition of 10 and 20 :
Answer : 30
2nd object created...
Addition of 10 and 20 :
Answer : 30
Objects are equal:false
Example 2
public class JavaObjectequalsExample2{
static int a = 10, b=20;
int c;
// Constructor
JavaObjectequalsExample2()
{
System.out.println("Addition of 10 and 20 : ");
c=a+b;
System.out.println("Answer : "+c);
}
JavaObjectequalsExample2(int x, int y)
{
System.out.println("Parameterized Constructors");
System.out.println("Addition " +x+ " and " +y);
c=x+y;
System.out.println("Answer : "+c);
}
// Driver code
public static void main(String args[])
{
System.out.println("1st object created...");
JavaObjectequalsExample2 obj1 = new JavaObjectequalsExample2();
System.out.println("2nd object created...");
JavaObjectequalsExample2 obj2 = new JavaObjectequalsExample2(2,3);
System.out.println("Objects are equal:" + obj1.equals(obj2));
}
}
Output:
1st object created...
Addition of 10 and 20 :
Answer : 30
2nd object created...
Parameterized Constructors
Addition 2 and 3
Answer : 5
Objects are equal:false
Object o1 = new Object();
Object o2 = new Object();
//o1=o2;
System.out.println(o1.equals(o2));
It returns false. It can return true, if the comment is removed.
The java string equals() method compares the two given strings based on the content of the
string. If any character is not matched, it returns false. If all characters are matched, it returns
true.
The String equals() method overrides the equals() method of Object class.
In general both equals() and “==” operator in Java are used to compare objects to check equality
but here are some of the differences between the two:
Main difference between .equals() method and == operator is that one is method and other is
operator.
We can use == operators for reference comparison (address comparison) and .equals() method
for content comparison. In simple words, == checks if both objects point to the same memory
location whereas .equals() evaluates to the comparison of values in the objects.
If a class does not override the equals method, then by default it uses equals(Object o) method of
the closest parent class that has overridden this method.
Coding Example:
getClass() : Returns the Class object of “this” object and used to get actual runtime class of the
object. It can also be used to get metadata of this class. The returned Class object is the object
that is locked by static synchronized methods of the represented class. As it is final so we don’t
override it.
syntax
public final Class getClass()
Note: After loading a .class file, JVM will create an object of the type java.lang.Class in the
Heap area. We can use this class object to get Class level information. It is widely used
in Reflection
finalize() method : This method is called just before an object is garbage collected. It is called by
the Garbage Collector on an object when garbage collector determines that there are no more
references to the object. We should override finalize() method to dispose system resources,
perform clean-up activities and minimize memory leaks. For example before destroying Servlet
objects web container, always called finalize method to perform clean-up activities of the
session.
Note :finalize method is called just once on an object even though that object is eligible for
garbage collection multiple times.
t = null;
System.out.println("end");
}
@Override
protected void finalize()
{
System.out.println("finalize method called");
}
}
Output:
366712642
finalize method called
end
clone() : It returns a new object that is exactly the same as this object. For clone() method
refer Clone()
The remaining three methods wait(), notify() notifyAll() are related to Concurrency. Refer Inter-
thread Communication in Java for details.
Class (java.lang.Class)
Reference:
https://www.geeksforgeeks.org/java-lang-class-class-java-set-1/
Java provides a class with name Class in java.lang package. Instances of the class Class
represent classes and interfaces in a running Java application. The primitive Java types (boolean,
byte, char, short, int, long, float, and double), and the keyword void are also represented as Class
objects. It has no public constructor. It is a final class, so we cannot extend it. The Class class
methods are widely used in Reflection API. Instead Class objects are constructed automatically
by the Java Virtual Machine as classes are loaded and by calls to the defineClass method in the
class loader.
The following example uses a Class object to print the class name of an object:
It is also possible to get the Class object for a named type (or for void) using a class literal.
For example:
System.out.println("The name of class Foo is: "+Foo.class.getName());
https://stackoverflow.com/questions/4453349/what-is-the-class-object-java-lang-class
Nothing gets typecasted to Class. Every Object in Java belongs to a certain class. That's why
the Object class, which is inherited by all other classes, defines the getClass() method.
getClass(), or the class-literal - Foo.class return a Class object, which contains some metadata
about the class:
name
package
methods
fields
constructors
annotations
and some useful methods like casting and various checks (isAbstract(), isPrimitive(), etc).
The above statement creates the Class object for the class passed as a String
argument(className). Note that the parameter className must be fully qualified name of the
desired class for which Class object is to be created. The methods in any class in java which
returns the same class object are also known as factory methods. The class name for which
Class object is to be created is determined at run-time.
2. Myclass.class : When we write .class after a class name, it references the Class object
that represents the given class. It is mostly used with primitive data types and only when
we know the name of class. The class name for which Class object is to be created is
determined at compile-time. Below is the syntax :
Class c = int.class
Please note that this method is used with class name, not with class instances. For example
A a = new A(); // Any class A
Class c = A.class; // No error
Class c = a.class; // Error
3. obj.getClass() : This method is present in Object class. It return the run-time class of
this(obj) object. Below is the syntax :
Methods:
1. String toString(): This method converts the Class object to a string. It returns the string
representation which is the string “class” or “interface”, followed by a space, and then by
the fully qualified name of the class. If the Class object represents a primitive type, then
this method returns the name of the primitive type and if it represents void then it returns
“void”.
Syntax :
public String toString()
Parameters :
NA
Returns :
a string representation of this class object.
Overrides :
toString in class Object
// toString method on c1
System.out.println(c1.toString());
// toString method on c2
System.out.println(c2.toString());
System.out.print("Class represented by c3: ");
// toString method on c3
System.out.println(c3.toString());
}
}
Output:
Class represented by c1: class java.lang.String
Class represented by c2: int
Class represented by c3: void
Syntax :
public static Class<?> forName(String className) throws ClassNotFoundException
Parameters :
className - the fully qualified name of the desired class.
Returns :
return the Class object for the class with the specified name.
Throws :
LinkageError : if the linkage fails
ExceptionInInitializerError - if the initialization provoked by this method fails
ClassNotFoundException - if the class cannot be located
The specified class loader is used to load the class or interface. If the parameter loader is null, the
class is loaded through the bootstrap class loader in. The class is initialized only if the initialize
parameter is true and if it has not been initialized earlier.
Syntax :
public static Class<?> forName(String className,boolean initialize, ClassLoader loader)
throws ClassNotFoundException
Parameters :
className - the fully qualified name of the desired class
initialize - whether the class must be initialized
loader - class loader from which the class must be loaded
Returns :
return the Class object for the class with the specified name.
Throws :
LinkageError : if the linkage fails
ExceptionInInitializerError - if the initialization provoked by this method fails
ClassNotFoundException - if the class cannot be located
// forName method
// it returns the Class object for the class
// with the specified name using the given class loader
Class c = Class.forName("java.lang.String",true,loader);
4. T newInstance() : This method creates a new instance of the class represented by this
Class object. The class is created as if by a new expression with an empty argument list.
The class is initialized if it has not already been initialized.
Syntax :
public T newInstance() throws InstantiationException,IllegalAccessException
TypeParameters :
T - The class type whose instance is to be returned
Parameters :
NA
Returns :
a newly allocated instance of the class represented by this object.
Throws :
IllegalAccessException - if the class or its nullary constructor is not accessible.
InstantiationException - if this Class represents an abstract class, an interface,
an array class, a primitive type, or void
or if the class has no nullary constructor;
or if the instantiation fails for some other reason.
ExceptionInInitializerError - if the initialization provoked by this method fails.
SecurityException - If a security manager, s, is present
new vs newInstance() :-
Reference:
https://www.oodlestechnologies.com/blogs/new-Operator-Vs-newInstance-method/
we can use new operator to create an Object if we know Class name at the beginig of exection of
program .
Example :-
1) newInstance() is a method present in class Class .We can use newInstance() method to create
object if we do not know class name at the begining and it is available dynamically at runtime .
Example :-
class Student
{
//some code here
}
class Customer
{
//some code here
}
class Test
{
public static void main(String[] args) throws Exception
{
Object object=Class.forName(args[0]).newInstance();
//Class.forName(args[0])
//class Class Object
System.out.println(“object created for”+o.getClass().getName());
}
}
2) In the case of new operator based on our requirement we can invoke any constructor .
Example : -
Test test1 =new Test();
Test test2=new Test(“himanshu”);
Test test2=new Test(“himanshu”,10.98);
But newInstance() method internally calls no-argument constructor . Hence to use newInstance()
method compulsory corresponding class should contain no-argument constructor. Otherwise we
will get RuntimeException saying InstatiationException .
3) While using new operator at runtime if the corresponding .file( .class file ) is not available
then we will get RuntimeException saying NoClassDefFoundError : Test
Example : -
At runtime if Test.class file not available then we will get RuntimeException saying
NoClassDefFoundError : Test
While using newInstance() method at runtime if the corresponding .class file is not available then
we will get RuntimeException saying ClassNotFoundException .
Example : -
At runtime if Test123.class file is not available then we will get RuntimeException saying
boolean isInstance(Object obj) : This method determines if the specified Object is assignment-
compatible with the object represented by this Class. It is equivalent to instanceof operator in
java.
Syntax :
public boolean isInstance(Object obj)
Parameters :
obj - the object to check
Returns :
true if obj is an instance of this class else return false
String s = "GeeksForGeeks";
int i = 10;
}
}
Output:
is s instance of String : true
is i instance of String : false
instanceof operator and isInstance() method both are used for checking the class of the object.
But main difference comes when we want to check the class of object dynamically. In this
case isInstance() method will work. There is no way we can do this by instanceof operator.
instanceof operator and isInstance() method both return a boolean value. Consider an example:
true
Now if we want to check the class of the object at run time, then we must
use isInstance() method.
System.out.println(b);
System.out.println(b1);
System.out.println(b2);
}
}
Output:
true
false
true
NOTE: instanceof operator throws compile time error(Incompatible conditional operand types)
if we check object with other classes which it doesn’t instantiate.
Please follow
https://www.geeksforgeeks.org/java-lang-class-class-java-set-1/
for remaining