Java 8 Interview Questions and Answers
Try Aihirely for
Smarter Interview Prep
Experience real-time AI support tailored to your Resume.
Boost your confidence and ace every question with
AI Mock Interview.
Question: How do you create a thread in Java?
Answer:
In Java, you can create a thread in two main ways:
- By extending the
Threadclass - By implementing the
Runnableinterface
Each method has its own use case, and the choice depends on your specific requirements.
1. Creating a Thread by Extending the Thread Class:
To create a thread by extending the Thread class, you need to follow these steps:
- Extend the
Threadclass. - Override the
run()method to define the task the thread will execute. - Create an instance of your subclass and call the
start()method to begin execution.
Example:
class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread is running...");
}
public static void main(String[] args) {
// Create an instance of MyThread
MyThread thread = new MyThread();
// Start the thread
thread.start();
}
}
Explanation:
- Step 1: The
MyThreadclass extends theThreadclass. - Step 2: The
run()method is overridden to define the task the thread will perform. - Step 3: The
start()method is called to begin executing the thread. Thestart()method internally calls therun()method.
2. Creating a Thread by Implementing the Runnable Interface:
Another way to create a thread is by implementing the Runnable interface. This is a more flexible approach, as it allows you to separate the thread’s task from the thread itself.
- Implement the
Runnableinterface. - Override the
run()method to define the task. - Pass the
Runnableinstance to aThreadobject and callstart().
Example:
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Runnable thread is running...");
}
public static void main(String[] args) {
// Create an instance of MyRunnable
MyRunnable myRunnable = new MyRunnable();
// Create a thread object and pass the Runnable to it
Thread thread = new Thread(myRunnable);
// Start the thread
thread.start();
}
}
Explanation:
- Step 1: The
MyRunnableclass implements theRunnableinterface and provides therun()method. - Step 2: The
run()method defines the task that will be executed by the thread. - Step 3: A new
Threadobject is created by passing theRunnableinstance to theThreadconstructor. Thestart()method is then called to begin execution.
3. Differences Between Extending Thread and Implementing Runnable:
| Aspect | Extending Thread | Implementing Runnable |
|---|---|---|
| Inheritance | Inherits from Thread class | Implements the Runnable interface |
| Task Definition | Task is defined in the run() method of the subclass | Task is defined in the run() method of the Runnable interface |
| Flexibility | Less flexible; can’t extend another class (because Java supports single inheritance) | More flexible; can implement multiple interfaces or extend another class |
| Usage | Less preferred for complex scenarios where multiple tasks need to be performed | Preferred in cases where you need more flexibility, especially when using thread pools |
| Resource Sharing | Not as suitable for sharing resources between threads (unless synchronized) | Better for sharing resources since it can be used with ExecutorService or thread pools |
4. Starting the Thread:
After creating the thread (either by extending Thread or implementing Runnable), you start the thread using the start() method. The start() method internally calls the run() method, but it executes the run() method in a separate thread of execution.
Important Notes:
- The
start()method initiates the thread, but does not immediately execute the code inside therun()method. Instead, it schedules the thread to run. - The
run()method is not executed directly; it is invoked by the Java Virtual Machine (JVM) when the thread is scheduled to run. - The
Threadclass also provides various methods for controlling the thread, such assleep(),join(), andinterrupt(), but these are usually used for advanced thread control.
Conclusion:
- Extend the
Threadclass when you want to define the thread’s behavior in the subclass and are not concerned about reusing the thread behavior in multiple classes. - Implement the
Runnableinterface when you need flexibility, such as when you want to define the thread’s task separately from the thread itself or when multiple threads need to share the same task.
Question: What is the purpose of the final keyword in Java?
Answer:
The final keyword in Java is used to define constants, prevent method overriding, and restrict inheritance. It can be applied to variables, methods, and classes, and it has different meanings depending on where it is used.
Here’s a breakdown of the different uses of final:
1. Final Variables:
When the final keyword is applied to a variable, it makes the variable constant, meaning that its value cannot be changed once it has been assigned.
- Primitive data types: If the variable is a primitive data type (e.g.,
int,float, etc.), it means the value cannot be modified. - Reference variables: If the variable is a reference type (e.g., an object), the reference (i.e., the memory address) cannot be changed, but the contents of the object itself can still be modified.
Example:
final int MAX_VALUE = 100; // The value of MAX_VALUE cannot be changed.
MAX_VALUE = 200; // Compile-time error: cannot assign a value to a final variable.
In the case of reference variables:
final StringBuilder sb = new StringBuilder("Hello");
sb.append(" World"); // This is allowed because the object is still mutable.
sb = new StringBuilder("New Value"); // Compile-time error: cannot reassign the reference.
2. Final Methods:
When the final keyword is applied to a method, it means the method cannot be overridden by subclasses.
This is useful for preventing modification of critical methods, such as methods that provide essential functionality or security measures.
Example:
class Animal {
public final void sound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
// This will result in a compile-time error because sound() is final in the parent class.
public void sound() {
System.out.println("Dog barks");
}
}
3. Final Classes:
When the final keyword is applied to a class, it means the class cannot be subclassed. This is used when you want to prevent inheritance from a particular class.
Example:
final class MathUtil {
public static int add(int a, int b) {
return a + b;
}
}
// This will result in a compile-time error because MathUtil is final and cannot be extended.
class AdvancedMathUtil extends MathUtil {
// Some code
}
4. Final Parameters:
The final keyword can also be applied to method parameters to indicate that the parameter cannot be reassigned within the method. It ensures that the value passed to the method remains unchanged throughout its execution.
Example:
public void calculateSum(final int a, final int b) {
// a = 10; // Compile-time error: cannot assign a value to final variable 'a'
System.out.println(a + b);
}
Key Points to Remember:
- Final Variables: Once assigned, their values cannot be changed.
- Final Methods: Cannot be overridden by subclasses.
- Final Classes: Cannot be subclassed or extended.
- Final Parameters: Cannot be modified inside the method.
Conclusion:
The final keyword in Java provides a way to define constants, enforce method behavior (prevent overriding), and prevent inheritance. It is a powerful tool for ensuring that certain aspects of your program remain immutable and fixed, which can help improve code reliability, security, and maintainability.
Read More
If you can’t get enough from this article, Aihirely has plenty more related information, such as Java interview questions, Java interview experiences, and details about various Java job positions. Click here to check it out.
