Java / Object, Class and Package
The java.lang.Cloneable interface must be implemented by the class whose objects would be cloned.
Implement the clone() method in the class protected Object clone()throws CloneNotSupportedException.
Object cloning is one of the ways to create a exact copy of a object.
Yes. However only one class can be declared as public and the java file name should be exactly same as the public class name along with .java extension.
java.lang.System
out is of type PrintStream and it is a static member in the System class.
No.
No.
java.lang.Object class.
Yes. The file is to be saved as .java without any file name.
compile using javac .java and run using java <className>
For e.g., .java file content:
class JavaClass { public static void main(String args[]) { System.out.println(".java file content"); } }
An anonymous class has no specified name declared and instantiated at the same time where it is declared. Because it has no name it can only be instantiated and used at the place of declaration. Anonymous classes either implement an interface or extend a class.
Anonymous classes are given a name by the compiler and they are treated as local inner classes.
Both of these errors are related to missing classes in the classpath, however the main difference lies how it originate.
ClassNotFoundException occurs when you try to load a class at runtime by using Class.forName() or loadClass() and requested class is not present in classpath. It is thrown when an application tries to load in a class through its name, but no definition for the class with the specified name could be found.
NoClassDefFoundError is encountered when the class was available at compile time but not during runtime.
package com.tutorials.classes; public class ExampleClassNotFoundException { private static final String CLASS_TO_LOAD = "com.tutorials.classes.NotCreatedClass"; public static void main(String[] args) { try { Class loadedClass = Class.forName(CLASS_TO_LOAD); System.out.println("Class " + loadedClass + " found successfully!"); } catch (ClassNotFoundException ex) { System.err.println("ClassNotFoundException was caught: " + ex.getMessage()); ex.printStackTrace(); } } }
A class can be loaded using one of the following methods:
- Class.forname,
- ClassLoader.findSystemClass,
- ClassLoader.loadClass.
Class.forName() uses the caller's classloader and initializes the class (runs static intitializers, etc.).
loadClass is a ClassLoader method, so it uses an explicitly-provided loader, and initializes the class lazily (on first use).
Java.lang.Object implements the clone() method.
Clonable is a marker interface and it does not have any methods.
Object.clone() is a native method implemented using C, C++ or any other native language.
Java default ClassLoader is sufficient to load files from local file system that helps most of the cases. In a scenario where we expect a class at the runtime or from FTP server or via third party web service at the time of loading the class then It may be required to create custom loader by extending the existing class loader. For example, AppletViewers load the classes from remote web server.
When JVM requests a Java class, it invokes loadClass method of the ClassLoader by passing the fully classified name of the Class. loadClass method calls findLoadedClass() method to check that the class has been already loaded or not.
If the Class is not already loaded then it will delegate the request to parent ClassLoader to load the class.
If the parent ClassLoader does not find the Class then it will invoke findClass() method to look for the class in the file system.
At runtime immediately after the class has been loaded.
Java ClassLoader is based on the following 3 principles.
Delegation principle delegates the classloading request to parent class loader and loads the class only if parent is not able to find or load class.
Visibility principle allows child class loader to access all the classes loaded by parent ClassLoader, while parent class loader cannot see classes loaded by its child.
Uniqueness principle allows to load a class exactly once.
Class loading is performed by ClassLoaders in Java which can be implemented to eagerly load a class as soon as another class references it or lazily load the class until a need of class initialization occurs.
If a Java class is loaded before its actually being used it resided at JVM before being initialized. This differs between JVM to JVM. While its guaranteed by JLS that a class will be loaded when there is a need of static initialization.
After class loading, initialization of class takes place by initializing all static members of class.
A Java class's static initialization usually happens immediately before the first time one of the following events occurs:
- an instance of the class is created,
- a static method of the class is invoked,
- a static field of the class is assigned,
- a non-constant static field is used, or
- for a top-level class, an assert statement lexically nested within the class is executed.
Reflection can also cause initialization of class. Some methods of java.lang.reflect package may cause class to be initialized.
Classes are initialized from top to bottom fashion so that fields declared on top initialized before field declared in bottom.
Super Class is initialized before Sub Class or derived class is initialized in Java.If Class initialization is triggered due to the access of a static field, only Class which has declared static field is initialized and it doesn't trigger initialization of super class or sub class even if static field is referenced by type of Sub Class, Sub Interface or by implementation class of interface.
interface initialization in Java doesn't cause super interfaces to be initialized.
static fields are initialized during static initialization of class while non static fields are initialized when instance of class is created. It means static fields are initialized before non static fields in Java.
non static fields are initialized by constructors in Java. sub class constructor implicitly call super class constructor before doing any initialization, which guarantees that non static or instance variables of super class is initialized before sub class.
The class defined inside a particular block is called local class. Such a class has local scope and isn't usable outside the block where it is defined.
Java supports 2 type of cloning: - Deep and shallow cloning. By default shallow clone is used in Java. Object class has a method clone() which does shallow cloning.
Shallow clone is a copying the reference pointer to the object, which mean the new object is pointing to the same memory reference of the old object. The memory usage is less in case of shallow copy.
Deep copy of an object will have exact copy of all the fields of original object just like shallow copy. But in additional, if original object has any references to other objects as fields, then copy of those objects are also created by calling clone() method on them. That means clone object and original object will be 100% disjoint. They will be 100% independent of each other. Any changes made to clone object will not be reflected in original object or vice-versa.
To create a deep copy of an object, you have to override the clone() method.
Shallow copy. | Deep copy. |
Cloned Object and the original object are not 100% disjoint. | Cloned Object and original object are 100% disjoint. |
Any changes to the cloned object will be reflected in original object or vice versa. | Changes made to cloned object won't be reflected to original object or vice versa. |
Default version of clone method creates the shallow copy of an object. | To create the deep copy of an object, you have to override clone method. |
Shallow copy is preferred if an object has only primitive fields. | Deep copy is preferred if an object has references to other objects as fields. |
Shallow copy is fast and cost effective. | Deep copy is slow and very expensive. |
Serialization is a process of writing an Java Object into file along with its attributes and content. It internally converts the object in stream of bytes.
De-Serialization is a process of reading the Java Object and its properties from a file along with the Object's content.
The readObject method is responsible for reading from the stream and restoring the classes fields.
readResolve is used for replacing the object read from the stream. This helps enforcing singletons; when an object is read, replace it with the singleton instance. This ensures that nobody can create another instance by serializing and deserializing the singleton.
The readResolve method is called when ObjectInputStream has read an object from the stream and is preparing to return it to the caller. ObjectInputStream checks whether the class of the object defines the readResolve method. If the method is defined, the readResolve method is called to allow the object in the stream to designate the object to be returned.
This method propagates any exception thrown by the nullary constructor (parameter-less), including checked exceptions. Use of this method effectively bypasses the compile-time exception checking that would otherwise be performed by the compiler.
The Constructor.newInstance method avoids this problem by wrapping any exception thrown by the constructor in a (checked) InvocationTargetException.
The static initializer block will be called on loading of the class, and will have no access to instance variables or methods. It is often used to create static variables.
The non-static initializer block is created on object construction only, will have access to instance variables and methods. It will be called at the beginning of the constructor, after the super constructor has been called (either explicitly or implicitly) and before any other subsequent constructor code is called.
Static class is a Java class, which only contains static methods. An example of static class is java.lang.Math,which contains utility static methods for various math features such as sqrt, random.
Runtime class provides access to the Java runtime system to retrieve information like memory availability, invoking the garbage collector, etc.
System class provides access to system resources. It enables access to standard input/output, error output streams, current time in millis, terminating the application, etc.
No.
protected Object clone() throws CloneNotSupportedException
Creates and returns a copy of this object.
public boolean equals(Object obj)
Indicates whether some other object is "equal to" this one.
protected void finalize() throws Throwable
Called by the garbage collector on an object when garbage collection determines that there are no more references to the object.
public final Class getClass()
Returns the runtime class of an object.
public int hashCode()
Returns a hash code value for the object.
public String toString()
Returns a string representation of the object.
The notify, notifyAll, and wait methods of Object all play a part in synchronizing the activities of independently running threads in a program. There are 5 of these methods:public final void notify()
public final void notifyAll()
public final void wait()
public final void wait(long timeout)
public final void wait(long timeout, int nanos)
No. It is a final method.
Shallow copy is preferred for cloning primitive types and immutable objects.
Consider that you are overriding equals method for Employee Class having empId, firstName and lastName.
- Check for reference equality, if equal then return true.
- Check for null check on the object argument being passed, if null return false.
- Compare getClass methods, if different return false.
- Always compare numeric and identify fields first.
- Check for field's references first and then check for null and equality.
- Override hashcode method whenever you override equals method.
The above steps are illustrated in the below example.
@Override public boolean equals(Object o) { if (this == o) // check 1 return true; // null check if (o == null) return false; // type check and cast if (getClass() != o.getClass()) return false; Employee emp = (Employee) o; //numeric and identity fields first if (!Objects.equals(this.emplId, emp.emplId)) return false; // field comparison return Objects.equals(firstName, emp.firstName) && Objects.equals(lastName, emp.lastName); }
As per the expert's recommendation, the below steps are listed.
- Create a int
hashcodeResult
and assign it a non-zero value. - For every field f tested in the equals method,calculates its hash code value
c
using the following.- If the field f is a boolean: calculate
(f ? 0 : 1)
; - If the field f is a byte, char, short or int: calculate (int)f;
- field f is a long, calculate
(int)(f ^ (f >>> 32))
; - field f is a float, calculate
Float.floatToIntBits(f)
; - field f is a double, calculate
Double.doubleToLongBits(f)
and use the long value; - If the field f is an object: Use the result of the hashCode() method or 0 if f == null;
- If the field f is an array, consider every field as separate element and calculate the hash value in a recursive fashion and combine the values.
- If the field f is a boolean: calculate
- Combine the hash value
c
withhashcodeResult.
hashcodeResult=37+c+ hashcodeResult
. - Return the value of
hashcodeResult
.
It is not strictly required, however the contract is compareTo should return 0 if equals returns true. TreeSet uses compareTo for ordering, ArrayList for sorting, so it is better to override compareTo as well.
Yes, possible. Two objects which are not equal to equals() method can still return same hashCode.
java.util.Set implementations such as SortedSet, TreeSet uses compareTo method for comparing objects. When compareTo does not return 0 while equals is true, it breaks Set contract and may result in duplicates.
instanceof operator returns true, even if compared with subclass, for example, Subclass instanceof Superclass is true, but with getClass() its false. By using getClass() you ensure that your equals() implementation doesn't return true if compared with subclass object.