Top 50 Core Java Interview Question Answers
Top 50 Core Java Interview Question Answers
Top 50 Core Java Interview Question Answers
INTERVIEW QUESTION
ANSWERS
ULTIMATE GUIDE TO CRACK YOUR NEXT
INTERVIEW
WWW.STAKTIPS.COM -1-
WWW.STACKTIPS.COM
JRE stands for Java Runtime Environment. It provides JVM and core libraries to run Java
applications. JRE is required for running compiled Java programs
JDK stands for Java Development Kit. It contains tools like compiler, debugger, and libraries for
the development of Java programs. You need JDK for developing Java applications
ClassLoader:
The ClassLoader is responsible for loading Java class files at runtime into the JVM. It doesn't
technically allocate a specific memory area, but it plays a crucial role in loading classes into
memory.
Heap:
The Heap is the runtime data area where all Java objects and arrays are allocated. It’s shared
among all threads. Heap is managed by Java’s garbage collection mechanism. The GC frees up
unused memory periodically.
Stack:
Each thread maintains its own Stack for storing frames. Each frame corresponds to a method
invocation and holds local variables, partial results, and return addresses. The stack is crucial for
method invocation and stores temporary data such as method arguments and local variables.
Unlike the heap, memory in the stack is freed as soon as the thread completes its method
execution.
-2-
WWW.STACKTIPS.COM
1. Bootstrap ClassLoader: This is the first ClassLoader. It loads classes from the jar file.
2. Extension ClassLoader: It loads class files from jre/lib/ext location.
3. Application ClassLoader: This ClassLoader depends on CLASSPATH to find the location of
class files. If you specify your jars in CLASSPATH, then this ClassLoader will load them.
• Constructors are called automatically when you create an object using a new operator
• The class name and the constructor name should be the same otherwise compiler treats
that as a method.
• A constructor can not have any return type, not even Void.
-3-
WWW.STACKTIPS.COM
Usually, a constructor is required in almost every Class. If no explicit constructor is declared, the
Java compiler provides a no-argument default constructor for each class.
In the following example, equals() returns true as the two string objects have the same
values. However, the == operator returns false as both string objects str1 and str2 are
referencing different objects.
//Reference comparison
System.out.println(s1 == s2);
//Content comparison
System.out.println(s1.equals(s2));
// integer-type
System.out.println(10 == 10);
// char-type
System.out.println('a' == 'a');
-4-
WWW.STACKTIPS.COM
Output
false
true
true
true
Method 1
This is because Java will automatically promote smaller numeric types to larger numeric types.
In this case, the integer literal 5 can be automatically promoted to either an int or a long, and
the integer literal 10 can also be promoted to either an int or a long.
-5-
WWW.STACKTIPS.COM
for (;;)
{
// Business logic
// Any break logic
}
while(true){
// Business logic
// Any break logic
}
do{
// Business logic
// Any break logic
} while(true);
Question 10: Explain the Diamond Problem. How does Java overcome
this problem?
The Diamond Problem is a situation where a class inherits from two classes that have a
common ancestor. This creates ambiguity in the path through which a method or a member
variable is inherited because there are 2 possible paths to follow up the inheritance hierarchy
to the common ancestor.
Java does not support multiple inheritance for classes, meaning a class cannot extend more
than one class. However, it supports multiple inheritance of types through the interface.
This provides the ability for interfaces to define new methods without breaking the
implementation for all classes that implement the interface.
-6-
WWW.STACKTIPS.COM
interface Vehicle {
String speedUp();
String slowDown();
To learn more about default methods for interfaces, visit this link.
Question 12: Explain how Java deals with the diamond problem due
to the default method in the interface.
With the introduction of Default methods in interfaces in Java 8, the potential for a diamond
problem arose. Default methods allow an interface to provide a default implementation for
methods, which means a class can inherit concrete methods from multiple interfaces.
1. Explicit Implementation:
If a class implements multiple interfaces that define the same default method, the class must
explicitly provide an implementation for that method to resolve the conflict.
2. Inheritance Rule:
If a class inherits a method from a superclass, it takes precedence over any default methods
provided by interfaces.
interface Interface1 {
default void hello() {
System.out.println("Hello from Interface1");
}
}
interface Interface2 {
default void hello() {
System.out.println("Hello from Interface2");
}
}
-7-
WWW.STACKTIPS.COM
Since default methods are not abstract you're free to add default methods to your functional
interface. We can use arbitrary interfaces as lambda expressions as long as the interface only
contains one abstract method.
To ensure your interface meets the requirements, you can optionally add
the @FunctionalInterface annotation. The compiler is aware of this annotation and throws
a compiler error as you try to add a second abstract method declaration to the interface.
@FunctionalInterface
interface Converter<F, T> {
T convert(F from);
}
-8-
WWW.STACKTIPS.COM
Although it might initially appear counterintuitive since abstract classes cannot be directly
instantiated, these constructors serve a crucial purpose by initializing the fields and can be
invoked during the instantiation of their concrete subclasses.
public int a;
public int b;
When a concrete subclass of an abstract class is instantiated, the constructor of the abstract
class is called first, either implicitly or through the use of super() by passing arguments.
-9-
WWW.STACKTIPS.COM
This process is known as constructor chaining and ensures that the initialization behavior
defined in the abstract class's constructor is executed.
The main method is always static because it belongs to the class, not an object. If not static, it’s
available to all objects, which isn’t acceptable to the JVM. The JVM calls the main method
based on the class name, not the object.
Java programs must have only one main method as execution starts from it.
While terminal operations return a result of a certain type, intermediate operations return the
stream itself so you can chain multiple method calls in a row.
Streams are created on a source, e.g. a java.util.Collection like lists or sets (maps are
not supported). Stream operations can either be executed sequentially or parallelly. Streams
can be created either by
calling Collection.stream() or Collection.parallelStream() method.
listItems
.stream()
.filter((s) -> s.startsWith("item3"))
.forEach(System.out::println);
- 10 -
WWW.STACKTIPS.COM
It is quite slow to work with a String. However, StringBuilder is the fastest in performing
operations. The speed of a StringBuffer is more than a String and less than a StringBuilder. (For
example, appending a character is fastest in StringBuilder and very slow in String because a new
memory is required for the new String with appended character.)
// String
String first = "Stacktips";
String second = new String("StackTips");
// StringBuffer
StringBuffer third = new StringBuffer("StackTips");
// StringBuilder
StringBuilder fourth = new StringBuilder("StackTips");
if(sb1.equals(sb2)) {
System.out.println("Equal");
} else {
System.out.println("Not Equal");
}
}
}
- 11 -
WWW.STACKTIPS.COM
This is because the equals() method in the StringBuilder class does not override the
equals() method from the Object class. In the Object class, the equals() method checks
for reference equality, meaning it returns true if and only if both references point to the same
object in memory.
Since sb1 and sb2 are references to two different StringBuilder objects even though they
contain the same sequence of characters, the equals() method inherited from the Object
class will return false.
• Overridden methods must have the same name, argument list, and return type.
• The overriding method may not limit the access of the method it overrides. Methods
may be overridden to be more public, not more private.
• The overriding method may not throw any exceptions that may not be thrown by the
overridden method.
A sub-class is a class that inherits from another class called a superclass. Sub-class can access all
public and protected methods and fields of its superclass.
- 12 -
WWW.STACKTIPS.COM
Question 21: What are the various access specifiers used for class
definition in Java?
Access specifiers are the keywords used before a class name that defines the access scope. The
types of access specifiers for classes are:
Following are some of the examples where Singleton classes are best suited:
• Project Configuration: A class that reads your project configuration can be made
Singleton. By making this singleton, you are allowing global access for all classes in your
application. If the project configs are stored in a file, it just reads once and holds on the
application cache. You don’t have to read the file multiple times.
• Application Log: The logger will be used everywhere in your application. It must be
initialized once and used everywhere
- 13 -
WWW.STACKTIPS.COM
• Analytics and Reporting: If you are using some kind of data analysis tool like Google
Analytics, you will notice that they are designed to be a singleton. It initializes once and
is used everywhere for each user action.
For the step-by-step guide to implementing singleton class, check out this link.
In the following example, the Loop is broken when the counter reaches 4.
if (counter == 4) {
break;
}
}
In the following example when the counter reaches 4, the loop jumps to the next iteration and
any statements after the continue keyword are skipped for the current iteration.
- 14 -
WWW.STACKTIPS.COM
For example, a constant with the name MAX_LIMIT is declared and assigned value:
When a method is declared as final, it can NOT be overridden by the subclasses. This method is
faster than any other method because they are resolved at compile time.
When a class is declared as final, it cannot be inherited. Example String, Integer, and other
wrapper classes.
Another key difference in the use of abstract classes and interfaces is that a class that
implements an interface must implement all the methods of the interface while a class that
inherits from an abstract class doesn’t require the implementation of all the methods of its
super class.
A class can implement multiple interfaces but it can extend only one abstract class.
- 15 -
WWW.STACKTIPS.COM
Question 28: Can we declare the main method of our class as private?
No, in Java, the main method cannot be declared as a private method. If the main method is
declared as private, it will not get any compilation error but, it will get the following runtime
error.
Error: Main method not found in class MainClass, please define the mai
n method as:
public static void main(String[] args)
If you want the JVM to recognize and execute it the main method needs to be public and static.
Question 30: How can we execute any code even before the main
method?
To execute your code before the main method, you can use a static initializer block. Any
statements inside this static initializer block will be first loaded by JVM and executed once
before the main() method.
static {
System.out.println("Executing static block");
}
Output:
- 16 -
WWW.STACKTIPS.COM
Implementing this interface will allow the object converted into a byte stream and transferred
over a network.
This stored metadata enables the deserialization process to reconstitute the objects and map
the stream data into the class attributes with the appropriate type every time an object is
serialized the Java serialization mechanism automatically computes a hash value.
So when the serialized object is retrieved, the JVM first evaluates the suid of the serialized class
and compares the suid value with one of the objects. If the suid values match, then the object is
said to be compatible with the class, and hence, it is de-serialized. If not, an
InvalidClassException exception is thrown.
Garbage collection (GC) helps to prevent memory leaks and manage the limited memory
available in Java applications. The typical GC process uses a Mark-and-Sweep algorithm.
- 17 -
WWW.STACKTIPS.COM
• Checked Exceptions are exceptions that the JAVA compiler requires us to handle. We
have to use the try, cache block to handle the exception or throw the exception up the
call stack
• For example, IOException, SQLException, etc are examples of checked exceptions.
• All modern Java IDEs (Integrated Development Environments) will show these errors
during the compilation time.
Unchecked exceptions:
• The Java compiler ignores the unchecked exceptions and we are not forced by the
compiler to handle it. Unchecked exceptions are those exceptions that extend
RuntimeException
• For example, NullPointerException, IllegalArgumentException, etc are examples of
unchecked exceptions.
• Though the Java compiler does not force us, we can still choose to handle this exception
to maintain the normal flow of the program.
The transient keyword in Java is used to mark fields in a class that should not be serialized when
the class is converted into a byte stream during serialization. When an object is serialized to
write to a file or sent over a network, fields marked as transient are excluded from the
serialization process.
In the following example, the password field is declared as transient meaning, it will not be
serialized. When we deserialize the user object, notice that the password will be null.
- 18 -
WWW.STACKTIPS.COM
@Override
public String toString() {
return "User{username='" + username + "', password='" + passwo
rd + "'}";
}
}
// Serialization
try (ObjectOutputStream oos = new ObjectOutputStream(new FileO
utputStream("user.txt"))) {
oos.writeObject(user);
} catch (IOException e) {
e.printStackTrace();
}
// Deserialization
try (ObjectInputStream ois = new ObjectInputStream(new FileInp
utStream("user.txt"))) {
User deserializedUser = (User) ois.readObject();
System.out.println(deserializedUser);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
- 19 -
WWW.STACKTIPS.COM
• writeExternal(ObjectOutput out): This method specifies how the object's data should
be written out during serialization.
• readExternal(ObjectInput in): This method specifies how the object's data should be
read back in during deserialization.
The default serialization mechanism saves all non-transient fields. However, in the case of
Externalizable, you must explicitly write and read each field. A public no-arg constructor is
needed when using an externalizable interface.
public User() {
}
@Override
public String toString() {
return "User{username='" + username + "', password='" + passwo
rd + "'}";
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(username); // Serialize object
out.writeObject(password);
}
@Override
public void readExternal(ObjectInput in) throws IOException, Class
NotFoundException {
this.username = (String) in.readObject(); // Deserialize objec
t
this.password = (String) in.readObject();
}
}
- 20 -
WWW.STACKTIPS.COM
Question 37: What is Reflection in Java? What are the uses of Java
Reflection?
Reflection in Java provides the ability to inspect and manipulate the structure and behavior of
classes, interfaces, fields, and methods at runtime.
1. Dynamic Instantiation
Reflection can be used to create an instance of classes dynamically without knowing the class at
compile time. This is often used in frameworks like dependency injection containers.
Question 38: How can we access the private method of a class from
outside the class?
Reflection can be used to access the private method of a class from outside the class.
We use getDeclaredMethod() to get an instance of a private method. Then we mark this
method accessible and finally invoke it.
Example:
- 21 -
WWW.STACKTIPS.COM
class ReflectionDemo {
public static void main(String[] args) throws Exception {
Class<?> c = Class.forName("com.stacktips.reflection.Foo");
Object obj = c.newInstance();
Method method = c.getDeclaredMethod("printHello", String.class
);
method.setAccessible(true);
method.invoke(obj, "John");
}
}
Question 39: How many objects does the following code create?
String s1="Hello World!";
String s2="Hello World!";
String s3="Hello World!";
The above code creates only one object. Since there is only one String Literal “HelloWorld”
created, all the references point to the same object. This saves memory usage.
1. Declare the Class as final to prevent it from being subclassed. The final keyword in
class declaration ensures that its immutability is not compromised by its subclass.
2. Make All Fields private and final to prevent direct access and as final to ensure
they are assigned only once, at the time of object creation.
3. Do not include any setter methods for fields. This way, once the object is constructed,
its state cannot be changed externally.
4. Initialize Fields using a copy constructor to prevent external modifications of mutable
fields after the object is created.
5. For fields that hold mutable objects, return a deep copy instead of the actual object to
prevent modifications from outside the class.
6. Avoid the clone method, instead return a deep copy of the object instead of a
reference to the object itself.
Example:
- 22 -
WWW.STACKTIPS.COM
// Mutable class
class Address {
private String street;
private String city;
- 23 -
WWW.STACKTIPS.COM
class Singleton {
private static Singleton INSTANCE = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return INSTANCE;
}
}
The downside to this is that the instance is created even if it’s never used.
class Singleton {
private static Singleton INSTANCE;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
- 24 -
WWW.STACKTIPS.COM
section when the instance is null. We need to use the volatile keyword for the instance to
ensure the visibility of changes to variables across threads.
class Singleton {
private volatile static Singleton INSTANCE;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
class Singleton {
private Singleton() {
}
Question 41: List some of the key features introduced in Java 17.
Java 17 introduced several important features including:
• Sealed Classes- Restricts which classes can inherit from a sealed class
• Pattern Matching for switch: Allows more expressive and concise switch statements and
reduces boilerplate code in type-checking scenarios
• Records: Provides a compact syntax for creating immutable data classes
• Text Blocks: Allows multi-line string literals without escape characters
- 25 -
WWW.STACKTIPS.COM
Question 42: Explain the concept of text blocks in Java. How do they
improve code readability?
Text blocks in Java improve the way multiline strings are handled in code. Traditionally very
difficult to read strings that span across multiple lines and require preserving formatting.
Java 17 introduced triple quotes ("""). Text inside triple quotes is called text blocks. The
compiler automatically strips incidental indentation and preserves formatting.
- 26 -
WWW.STACKTIPS.COM
The fields of a record are implicitly final, which means that once a record instance is created,
the data it contains cannot be changed.
Records provide several built-in methods for common operations such as constructors,
getters, equals(), hashCode(), and toString(). Like a regular class, methods inside the
record can be extended to provide a custom implementation.
Records allow you to define a Compact constructor which omits the parameter list, assuming
the same parameters as the record components. Within this constructor, you can include
validation or normalization logic for the fields.
// Compact constructor
public Vehicle {
if (year < 1886) { // The first car was made in 1886
throw new IllegalArgumentException("Invalid year");
}
make = make.trim();
model = model.trim();
}
}
Records are ideal for creating simple data-carrier classes, such as DTOs (Data Transfer Objects),
value objects in domain-driven design, tuples, and more. Records are serializable by default,
provided that all their components are serializable.
- 27 -
WWW.STACKTIPS.COM
feature is useful to create more robust and maintainable code and to define a closed hierarchy
of types.
Sealed Classes allow you to specify a limited set of subclasses that can extend a given class or
implement an interface.
@Override
public void displayVehicleInfo() {
System.out.println("Car: " + getMake() + " " + getModel() + ",
Seating Capacity: " + seatingCapacity);
}
}
The permits clause is used to specify the allowed subclasses for type Shape.
Since the compiler knows all the possible subtypes of a sealed class, it will prevent any other
class except Circle, Square, or Rectangle from extending the Shape class.
Question 45: How Sealed classes are different from final classes?
Sealed classes and final classes serve different purposes in Java, although both are used to
restrict inheritance.
- 28 -
WWW.STACKTIPS.COM
• Final Classes in Java cannot be inherited at all. It can be used when a class should never
be extended.
• Sealed Classes can be inherited, but only by a predefined set of classes. It is used when
you want to allow inheritance, but only for specific classes.
Question 46: How does the pattern matching for instanceof work in
Java 17?
Pattern Matching for instanceof in Java 17 enhances the instanceof operator and
eliminates the need for type casting and checking.
Traditional approach:
As you can notice, it makes the code more concise but also enhances readability and reduces
the possibility of errors, such as incorrect casting.
Question 47: How does the Pattern matching for the switch work?
Pattern Matching for the switch is introduced as a preview feature in Java 17. This feature
extends the switch expression and switch statement to allow pattern matching in case labels.
Pattern Matching for switch aims to make code more readable and safe, especially when
dealing with type testing and casting.
Please note, that the Pattern Matching for the switch is still in preview and not yet finalized.
switch (obj) {
case String s -> System.out.println("It's a string: " + s);
case Integer i -> System.out.println("It's an integer: " + i);
case null -> System.out.println("It's null");
default -> System.out.println("It's something else");
}
- 29 -
WWW.STACKTIPS.COM
Question 49: How does the new Random Number Generators API in
Java 17 improve upon the previous implementation?
The new Random Number Generators API in Java 17 introduced a new RandomGenerator
interface as the top-level interface for random number generators. It provides specialized
interfaces like SplittableRandomGenerator, JumpableRandomGenerator, and
LeapableRandomGenerator for different types of generators.
It includes algorithms like LXM, Xoroshiro128PlusPlus, and Xoshiro256PlusPlus, which are more
modern and efficient than the older Linear Congruential Generator (LCG) used in the legacy
Random class.
The new API interface offers better control over the sequence of random numbers generated
and provides methods to "jump" or "leap" ahead in the sequence without generating
intermediate values.
import java.util.random.RandomGenerator;
import java.util.random.RandomGeneratorFactory;
System.out.println(split1.nextInt());
- 30 -
WWW.STACKTIPS.COM
System.out.println(split2.nextInt());
}
}
The Supplier interface does not accept an argument and produces a return value of any data
type. It is useful when you want to generate values lazily or return a constant value on demand.
Example:
The Consumer interface accepts an argument of any data type and it does not return any
value, It is useful when you need to act on an input, such as printing or logging values.
Example:
- 31 -
WWW.STACKTIPS.COM
In addition to my day job, I drive great satisfaction from mentoring aspiring developers and
sharing my expertise through my blog www.stacktips.com. During my mentoring sessions, I
frequently receive many requests for a comprehensive set of interview preparation questions.
This book is a culmination of my accumulated knowledge and experiences shared with my
mentees over the years.
You can find more information about me on my blog stacktips.com. If you’d like to connect with
me directly, you can find me on X under the handle @asknilan.
Finally, I want to express my gratitude to all of you for choosing this book. I hope you find this
guide useful in preparing for your next technical interview.
THANK YOU!
Thank you for reading this e-book. I hope you find all the necessary information here. Should
you have any questions, or queries, or simply wish to engage in a conversation, please do not
hesitate to contact me via [email protected]. I will promptly respond to your inquiries.
If you’re not already a member, don't forget to head to www.stacktips.com and sign up for
your free account. It is packed with tons of step-by-step tutorials, free courses, and goodies.
Finally, I would like to extend my best wishes for your upcoming interview. I am sure you’re
going to knock the next one.
- 32 -