Java Interview Questions and Answers

Embark on a journey into the world of Java programming with 'Java Interview Questions and Answers.' This blog is your indispensable resource for preparing for Java-related interviews, featuring an extensive collection of questions and comprehensive answers. Whether you're a Java developer, a software engineer, or a programming enthusiast, our guide covers Java fundamentals, object-oriented principles, and advanced topics. Prepare with confidence and explore the power of Java in software development and beyond.

1. What is Java?

Java is a high-level, object-oriented programming language developed by Sun Microsystems. It is platform-independent and designed to be portable, secure, and easy to use.

2. Explain the difference between "==" and ".equals()" in Java.

"==" compares object references, while ".equals()" compares the actual content of objects. In most cases, ".equals()" is used for comparing the content of strings and objects.

3. Describe the newly added features in Java 8?

Here are the newly added features of Java 8:

Feature Name Description
Lambda expression A function that can be shared or referred to as an object.
Functional Interfaces Single abstract method interface.
Method References Uses function as a parameter to invoke a method.
Default method It provides an implementation of methods within interfaces enabling 'Interface evolution' facilities.
Stream API Abstract layer that provides pipeline processing of the data.
Date Time API New improved joda-time inspired APIs to overcome the drawbacks in previous versions
Optional Wrapper class to check the null values and helps in further processing based on the value.
Nashorn, JavaScript Engine An improvised version of JavaScript Engine that enables JavaScript executions in Java, to replace Rhino.

4. In which programming paradigm Java 8 falls?

5. What are the significant advantages of Java 8?

6. What are functional or SAM interfaces?

Functional Interfaces are an interface with only one abstract method. Due to which it is also known as the Single Abstract Method (SAM) interface. It is known as a functional interface because it wraps a function as an interface or in other words a function is represented by a single abstract method of the interface.

Functional interfaces can have any number of default, static, and overridden methods. For declaring Functional Interfaces @FunctionalInterface annotation is optional to use. If this annotation is used for interfaces with more than one abstract method, it will generate a compiler error.

@FunctionalInterface // Annotation is optional public interface Foo() { // Default Method - Optional can be 0 or more public default String HelloWorld() { return "Hello World"; } // Static Method - Optional can be 0 or more public static String CustomMessage(String msg) { return msg; } // Single Abstract Method public void bar(); } public class FooImplementation implements Foo { // Default Method - Optional to Override@Overridepublic default String HelloWorld() { return "Hello Java 8"; } // Method Override@Overridepublic void bar() {\tSystem.out.println(“Hello World”);} } public static void main(String[] args) { FooImplementation fi = new FooImplementation();System.out.println(fi.HelloWorld());System.out.println(fi.CustomMessage(“Hi”));;}

7. Can a functional interface extend/inherit another interface?

A functional interface cannot extend another interface with abstract methods as it will void the rule of one abstract method per functional interface. E.g:

interface Parent { public int parentMethod(); } @FunctionalInterface // This cannot be FunctionalInterface interface Child extends Parent { public int childMethod(); // It will also extend the abstract method of the Parent Interface // Hence it will have more than one abstract method // And will give a compiler error }

It can extend other interfaces which do not have any abstract method and only have the default, static, another class is overridden, and normal methods. For eg:

interface Parent { public void parentMethod(){ System.out.println("Hello"); } } @FunctionalInterface interface Child extends Parent { public int childMethod(); }

8. What is the default method, and why is it required?

A method in the interface that has a predefined body is known as the default method. It uses the keyword default. default methods were introduced in Java 8 to have 'Backward Compatibility in case JDK modifies any interfaces. In case a new abstract method is added to the interface, all classes implementing the interface will break and will have to implement the new method. With default methods, there will not be any impact on the interface implementing classes. default methods can be overridden if needed in the implementation. Also, it does not qualify as synchronized or final.

@FunctionalInterface // Annotation is optional public interface Foo() { // Default Method - Optional can be 0 or more public default String HelloWorld() { return "Hello World"; } // Single Abstract Method public void bar(); }

9. What are static methods in Interfaces?

Static methods, which contains method implementation is owned by the interface and is invoked using the name of the interface, it is suitable for defining the utility methods and cannot be overridden.

10. What are some standard Java pre-defined functional interfaces?

Some of the famous pre-defined functional interfaces from previous Java versions are Runnable, Callable, Comparator, and Comparable. While Java 8 introduces functional interfaces like Supplier, Consumer, Predicate, etc. Please refer to the java.util.function doc for other predefined functional interfaces and its description introduced in Java 8.

Runnable: use to execute the instances of a class over another thread with no arguments and no return value. 

Callable: use to execute the instances of a class over another thread with no arguments and it either returns a value or throws an exception.

Comparator: use to sort different objects in a user-defined order

Comparable: use to sort objects in the natural sort order

11. What are the various categories of pre-defined function interfaces?

Function: To transform arguments in returnable value.

Predicate: To perform a test and return a Boolean value.

Consumer: Accept arguments but do not return any values.

Supplier: Do not accept any arguments but return a value. 

Operator: Perform a reduction type operation that accepts the same input types.

12. What is the lambda expression in Java and How does a lambda expression relate to a functional interface?

Lambda expression is a type of function without a name. It may or may not have results and parameters. It is known as an anonymous function as it does not have type information by itself. It is executed on-demand. It is beneficial in iterating, filtering, and extracting data from a collection.

As lambda expressions are similar to anonymous functions, they can only be applied to the single abstract method of Functional Interface. It will infer the return type, type, and several arguments from the signature of the abstract method of functional interface.

13. What is the basic structure/syntax of a lambda expression?

FunctionalInterface fi = (String name) -> { System.out.println("Hello "+name); return "Hello "+name; }

Lambda expression can be divided into three distinct parts as below:

1. List of Arguments/Params:

(String name) 

A list of params is passed in () round brackets. It can have zero or more params. Declaring the type of parameter is optional and can be inferred for the context. 

2. Arrow Token:

Arrow token is known as the lambda arrow operator. It is used to separate the parameters from the body, or it points the list of arguments to the body. 3. Expression/Body:

{ System.out.println("Hello "+name); return "Hello "+name; }

A body can have expressions or statements. {} curly braces are only required when there is more than one line. In one statement, the return type is the same as the return type of the statement. In other cases, the return type is either inferred by the return keyword or void if nothing is returned.

14. What are the features of a lambda expression?

Below are the two significant features of the methods that are defined as the lambda expressions: 

15. What is a type interface?

Type interface is available even in earlier versions of Java. It is used to infer the type of argument by the compiler at the compile time by looking at method invocation and corresponding declaration.

16. What are the types and common ways to use lambda expressions?

A lambda expression does not have any specific type by itself. A lambda expression receives type once it is assigned to a functional interface. That same lambda expression can be assigned to different functional interface types and can have a different type.

For eg consider expression s -> s.isEmpty() :

Predicate<String> stringPredicate = s -> s.isEmpty(); 
Predicate<List> listPredicate = s -> s.isEmpty();
Function<String, Boolean> func = s -> s.isEmpty();
Consumer<String> stringConsumer = s -> s.isEmpty();

Common ways to use the expression

Assignment to a functional Interface —> Predicate<String> stringPredicate = s -> s.isEmpty();
Can be passed as a parameter that has a functional type —> stream.filter(s -> s.isEmpty())
Returning it from a function —> return s -> s.isEmpty()
Casting it to a functional type —> (Predicate<String>) s -> s.isEmpty()

17. In Java 8, what is Method Reference?

Method reference is a compact way of referring to a method of functional interface. It is used to refer to a method without invoking it. :: (double colon) is used for describing the method reference. The syntax is class::methodName

For e.g.: 

Integer::parseInt(str) \\\\ method reference

str -> Integer.ParseInt(str); \\\\ equivalent lambda

18. What does the String::ValueOf expression mean?

It is a static method reference to method Valueof() of class String. It will return the string representation of the argument passed.

19. What are the advantages of using the Optional class?

Below are the main advantage of using the Optional class: 

It encapsulates optional values, i.e., null or not-null values, which helps in avoiding null checks, which results in better, readable, and robust code It acts as a wrapper around the object and returns an object instead of a value, which can be used to avoid run-time NullPointerExceptions.

20. What are the sources of data objects a Stream can process?

A Stream can process the following data:

21. What are Intermediate and Terminal operations?

Intermediate Operations:

Terminal Operations:

int count = Stream.of(1, 2, 3, 4, 5).filter(i -> i <4) // Intermediate Operation filter.count(); // Terminal Operation count

22. What are the most commonly used Intermediate operations?

Filter(Predicate<T>) - Allows selective processing of Stream elements. It returns elements that are satisfying the supplied condition by the predicate.

map(Funtion<T, R>) - Returns a new Stream, transforming each of the elements by applying the supplied mapper function.= sorted() - Sorts the input elements and then passes them to the next stage.

distinct() - Only pass on elements to the next stage, not passed yet.

limit(long maxsize) - Limit the stream size to maxsize.

skip(long start) - Skip the initial elements till the start.

peek(Consumer) - Apply a consumer without modification to the stream.

flatMap(mapper) - Transform each element to a stream of its constituent elements and flatten all the streams into a single stream.

23. What is the stateful intermediate operation? Give some examples of stateful intermediate operations.

To complete some of the intermediate operations, some state is to be maintained, and such intermediate operations are called stateful intermediate operations. Parallel execution of these types of operations is complex.

For Eg: sorted() , distinct() , limit() , skip() etc. 

Sending data elements to further steps in the pipeline stops till all the data is sorted for sorted() and stream data elements are stored in temporary data structures.

24. What is the most common type of Terminal operations?

25. What is the difference between findFirst() and findAny()?

findFirst() findAny()
Returns the first element in the Stream Return any element from the Stream
Deterministic in nature Non-deterministic in nature

26. How are Collections different from Stream?

Collections are the source for the Stream. Java 8 collection API is enhanced with the default methods returning Stream<T> from the collections.

Collections Streams
Data structure holds all the data elements No data is stored. Have the capacity to process an infinite number of elements on demand
External Iteration Internal Iteration
Can be processed any number of times Traversed only once
Elements are easy to access No direct way of accessing specific elements
Is a data store Is an API to process the data

27. What is the feature of the new Date and Time API in Java 8?

28. What are the important packages for the new Data and Time API?

29. Explain with example, LocalDate, LocalTime, and LocalDateTime APIs.




30. Define Nashorn in Java 8

Nashorn is a JavaScript processing engine that is bundled with Java 8. It provides better compliance with ECMA (European Computer Manufacturers Association) normalized JavaScript specifications and better performance at run-time than older versions.

31. Differentiate between Volatile and Transient Variable in Java.

Volatile Variable Transient Variable
The volatile keyword against the variable indicates that the content of the variable is stored in the main memory and every read of the variable should be done from the main memory and not the CPU cache and every write should be written to the main memory and not just to the CPU cache. Transient is used when we do not want the variable to be serialised.
Volatile ensures that the JVM does not re-order the variables and ensures that the synchronization issues are avoided. Transient provides flexibility and control over the attributes of objects from being serialized.
Volatile variables do not have any default values. Transient variables are initialized with default value corresponding to the data type at the time of deserialization.
Volatile variables can be used along with the static keyword. Transient variables cant be used along with static keywords because the static variables are class-level variables and not related to the individual instances. This matters during serialization.
Volatile variables can be used along with the final keyword. It is not recommended to use final with transient variables as it would cause problems for re-initializing the variables once the values are populated by default at the time of deserialization.

32. Differentiate between the Vector and ArrayList collections in Java.

ArrayList and Vector collection classes both implement the List interface and are derived from AbstractList. Both these classes are index-based, meaning objects can be retrieved from the collection based on the index using the get(index) method.

Category Vector ArrayList
Synchronization Vector is synchronized and thread-safe by default. This means that the internal state of the Vector is not compromised even if multiple threads are operating on it. ArrayList is neither thread-safe nor synchronized.
Speed Since Vector is synchronized, it works relatively slower than ArrayList. ArrayList is faster than Vector because there is no overhead of maintaining synchronization.

33. What do you understand by the ... in the below method parameters?

public void someMethod(String... info){   // method body}

The 3 dots feature was started in Java 5 and the feature is known as varargs (variable arguments). This simply means that the method can receive one or more/multiple String arguments as shown below:

These received arguments can be used as an array and can be accessed by iterating through loops as shown below:

public void someMethod(String... info){   for(String someInfo : info){       // any operation   }   // The info can be accessed using index based loops too   for( int i = 0; i < info.length; i++){       String s = info[i];       //some operation   }}

34. Can you write a code for representing thread-safe singleton patterns in Java?

A thread-safe singleton class is created which helps in object initialization in the presence of multiple threads. It can be done using multiple ways:

public enum ThreadSafeSingleton{   SINGLETON_INSTANCE;   public void display(){       System.out.println("Thread-safe singleton Display");   }}// The Singleton class methods can be invoked as;
public class ThreadSafeSingleton{   private static final ThreadSafeSingleton INSTANCE = new ThreadSafeSingleton();   private ThreadSafeSingleton(){ }   public static ThreadSafeSingleton getInstance(){       return INSTANCE;   }   public void display(){       System.out.println("Thread-safe Singleon");   }}ThreadSafeSingleton.getInstance().display();

But the disadvantage of this way is that the initialization cannot be done lazily and the getInstance() method is called even before any client can call.

public class ThreadSafeSingleton{ // Creating private instance to make it accessible only by getInstance() method private static ThreadSafeSingleton instance; private ThreadSafeSingleton() {   // Making constructor private so that objects cant be initialized outside the class } //synchronized getInstance method synchronized public static ThreadSafeSingleton getInstance(){   if (this.instance == null)   {     // if instance is null, initialize     this.instance = new ThreadSafeSingleton();   }   return this.instance; }}
public class ThreadSafeSingleton {  // Creating private instance to make it accessible only by getInstance() method private static ThreadSafeSingleton instance; private ThreadSafeSingleton(){   // Making constructor private so that objects cant be initialized outside the class } public static ThreadSafeSingleton getInstance(){   if (instance == null){     //synchronized block of code     synchronized (ThreadSafeSingleton.class){       if(instance==null)       {         // initialize only if instance is null         instance = new ThreadSafeSingleton();       }           }   }   return instance; }}

35. What is the importance of the hashCode() and equals() contract?

Consider the scenario of the HashMap object. We know that the Key of the HashMap uses the hashCode() and equals() methods for finding index or finding the value of a given key by uniquely identify the key-value pair in the map. If these methods are not implemented properly, then there are chances where two keys would produce the same output for these methods resulting in inaccuracy and a wrong key’s value might get updated at the time of updation. Hence, it is very much important to implement the hashCode and the equals method correctly. This can be done properly if we follow the hashCode-equals contract. The contract states that

If two objects are equal, then the hashCode method should produce the same result for both objects.
To ensure this, we have to override the hashCode() method whenever we override the equals() method.

36. How is the classpath variable different from the path variables?

The classpath variables are specific to the Java executables and are used for locating the class files. Whereas, the path variable is a variable present in the operating system and is used for locating the system executables.

37. What is the result of the below code and Why?

public class TestClass {public static void main(String[] args) {     someMethod(null);}public static void someMethod(Object o) { System.out.println("Object method Invoked");}public static void someMethod(String s) { System.out.println("String method Invoked");}}

The output of this code is “String method Invoked”. We know that null is a value that can be assigned to any kind of object reference type in Java. It is not an object in Java. Secondly, the Java compiler chooses the method with the most specific parameters in method overloading. this means that since the String class is more specific, the method with String input parameter is called.

38. How would you help a colleague with lesser Java experience who has trouble in serializing a class?

I would first check if the colleague has implemented the interface. If this is done, I will check if they are trying to serialize only non-static members since the static members cannot be serialized. I would also check if the fields that are not serialized are defined as transient accidentally.

39. What is the best possible way to call the wait() method - by using the if construct or the loop construct?

wait() should be called in loop construct always because whenever a thread gets resources to execute again, it is always better to check the condition before execution. The standard way of wait and notify usage is as shown below:

synchronized (resource) {   while (wait condition)     resource.wait(); // release the resource lock and reacquire it post wait   // operations to perform}

40. Can we use HashMap in a multi-threaded environment?

You can use the HashMap but the probability of working fine depends on the way we use it. For instance, consider the HashMap of configuration properties, if the HashMap initialization was done by using just one thread, and the remaining threads do the task of reading from the map, then HashMap would work perfectly well.

The problem arises when there is at least one thread that updates the Map by means of adding, updating, or deleting the map content. The put() method of the map resizes the map that can cause a deadlock or infinite loop while the threads operate. Hence, during such scenarios, we can use the HashTable or ConcurrentHashMap.

41. What is the result of the below code?

public class InterviewbitProblem{public static void main(String[] arr){   System.out.println(0.1*3 == 0.3);   System.out.println(0.1*2 == 0.2);}}

The statements result in:
System.out.println(0.1*3 == 0.3); -> Prints false
System.out.println(0.1*2 == 0.2); -> Prints true

This expectation mismatch is due to the error that occurs while rounding float-point numbers and the fact that in Java, only the floating-point numbers that are powers of 2 are represented accurately by the binary representation. The rest of the numbers should be rounded to accommodate the limited bits as required.

42. What will happen if you run 1.0/0.0?

The double class provides certain rules like Double.INFINITY, NaN, -0.0, etc which aids in arithmetic calculations. The given problem will return Double.INFINITY without throwing any Arithmetic Exception.

43. Is it possible to override a method to throw RuntimeException from throwing NullPointerException in the parent class?

Yes, this is possible. But it is not possible if the parent class has a checked Exception. This is due to the below rule of method overriding in cases of checked exceptions:

The method that wants to override a parent class method can not throw a higher Exception than the overridden method.

This means that if the overridden method is throwing IOException, then the overriding child class method can only throw IOException or its sub-classes. This overriding method can not throw a higher Exception than the original or overridden method.

44. Is there any difference in defining or creating a String by using String literal and by using the new() operator?

Creating string using the new operator ensures that the String is created in the heap alone and not into the string pool. Whereas, creating string using literal ensures that the string is created in the string pool. String pool exists as part of the perm area in the heap. This ensures that the multiple Strings created using literal having same values are pointed to one object and prevents duplicate objects with the same value from being created.

45. What is the output of the below code?

public class InterviewbitProblem{   public static void main(String[] args) {       Integer num1 = 1000, num2 = 1000;         System.out.println(num1 == num2);//1       Integer num3 = 20, num4 = 20;         System.out.println(num3 == num4);//2   }}

Line 1 results in false, whereas line 2 results in true. Let us see why.
In Java, if the references point to different objects and have the same content, they are not equal in terms of using double equals. By this logic, the statement num3==num4 should have resulted in false. But, the class in Java has a private inner class called which helps to cache the Integer objects ranging from -128 to 127. All the numbers lying between this range are cached internally by the Integer class. While defining an object as:

Integer num3 = 20;

Internally, it is converted to Integer by using:

Integer num = Integer.valueOf(20);

The valueOf method from the Integer class is defined like:

public static Integer valueOf(int i) { if (i >= IntegerCache.low && i<=IntegerCache.high)     return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i);}

This means that if the value lies in the range -128 to 127, then it returns the Integer instance from the cache, else it creates a new instance. This means that the num3 and num4 point to the same object in the IntegerCache and thereby the comparison results in true.

46. What is the result of the below program?

class X {   static int i = 1111;   static{       i = i-- - --i;    //L1   }   {       i = i++ + ++i;    //L2   }}class Y extends X{   static{       i = --i - i--;    //L3   }   {       i = ++i + i++;    //L4   }}public class DriverClass{   public static void main(String[] args){       Y y = new Y();       System.out.println(y.i);    //L5   }}

Let us evaluate the expressions one by one:
L1 ->

i = i-- - --i; i = 1111 - 1109 = 2

L2 ->

i = i++ + ++i; i = 0 + 2 = 2

L3 ->

i = --i - i--;i = 1 - 1 = 0

L4 ->

i = ++i + i++;i = 3 + 3 = 6 = y.i

L5 ->
y.i = i from class Y which is 6.
Hence the output is 6.

47. What is the output of the below code and why?

public class InterviewbitTest {   private static int counter = 0;   void InterviewbitTest() {       counter = 20;   }   InterviewbitTest(int x){       counter = x;   }   public static void main(String[] args) {       InterviewbitTest interviewbitTest = new InterviewbitTest();       System.out.println(counter);   }}

The output of the code is “Compile Error” This is because the code is not able to find any constructor that matches InterviewbitTest().

48. Is it necessary to declare all immutable objects as final?

This is not necessary. The functionality of achieving immutability can also be achieved by defining the members of a class as private and not providing any setter methods to modify/update the values. Any references to the members should not be leaked and the only source of initializing the members should be by using the parameterized constructor.

We should note that the variables declared as final only takes care of not re-assigning the variable to a different value. The individual properties of an object can still be changed.

49. What do you know about Factory Design Pattern in Java?

Factory design pattern is the most commonly used pattern in Java. They belong to Creational Patterns because it provides means of creating an object of different instances. Here, the logic of object creation is not exposed to the client. It is implemented by using a standard interface. It gives provision to select object types that we need for creation. This is why, they are also known as Virtual Constructors. For more information regarding the implementation, you can refer here.