Part 1 covers the questions that open almost every fresher Java interview: abstract class versus interface, the two families of exceptions, writing your own exception, serialization, marker interfaces, singletons and the old "why no multiple inheritance" question. The answers are written for Java 21 and 25, so where something changed since Java 8 you will see it called out.
Read the question, close your eyes and answer it aloud in two or three sentences before you look at mine. If your answer was vague, read mine, then say it again with a small example of your own. That second attempt is what sticks.
Q1. How is an abstract class different from an interface in Java?
An abstract class is a partly built class. It can hold instance fields, constructors, concrete methods with any access level, and some abstract methods left for subclasses. An interface describes a capability. Its fields are always public static final constants, it has no constructors, and it cannot hold per-object state.
The old answer "interfaces contain no code" stopped being true in Java 8. Interfaces can now have default and static methods, and since Java 9 private methods as well. The difference that still matters most is inheritance: a class can extend only one class (abstract or not) but can implement many interfaces.
| Point | Abstract class | Interface |
|---|---|---|
| State (instance fields) | Yes | No, only constants |
| Constructors | Yes, called via super() | No |
| Method bodies | Any concrete methods | default, static, private (Java 8/9+) |
| How many per class | One | Many |
| Use it when | Related classes share code and state | Unrelated classes share a behaviour |
Q2. Explain checked and unchecked exceptions with examples.
Checked exceptions are subclasses of Exception that are not under RuntimeException. The compiler forces you to either catch them or declare them with throws. They represent problems a correct program can still face, like a missing file (IOException) or a database failure (SQLException).
Unchecked exceptions extend RuntimeException, and the compiler does not force you to handle them. They usually mean a bug: NullPointerException, ArrayIndexOutOfBoundsException, ArithmeticException for integer division by zero. Note that OutOfMemoryError is not an exception at all. It is an Error, a separate branch under Throwable that you normally do not catch. Java also has no class called DivideByZeroException; that name is from C#.
Q3. How do you create and use your own exception class?
Extend Exception if callers should be forced to deal with it, or RuntimeException if it signals a programming mistake. Give it a constructor that passes a message (and optionally a cause) to super. Then throw it where the problem is detected, and either catch it or declare it in the method's throws clause.
class InsufficientBalanceException extends Exception {
InsufficientBalanceException(String message) {
super(message);
}
}
public class BankDemo {
static void withdraw(int balance, int amount) throws InsufficientBalanceException {
if (amount > balance) {
throw new InsufficientBalanceException("Need " + amount + ", have " + balance);
}
System.out.println("Withdrawn " + amount);
}
public static void main(String[] args) {
try {
withdraw(500, 200);
withdraw(500, 800);
} catch (InsufficientBalanceException e) {
System.out.println("Caught: " + e.getMessage());
}
}
}
Withdrawn 200
Caught: Need 800, have 500
Name custom exceptions after the problem, not the layer (InsufficientBalanceException, not ServiceException). Interviewers like hearing that.
Q4. What are the main differences between C++ and Java?
The syntax looks alike, but the two languages make very different trade-offs. The points worth listing:
- Java has no pointer arithmetic. You work with references, and the JVM checks array bounds.
- Memory is freed by the garbage collector. There are no destructors and no
delete. - Java compiles to bytecode that runs on any JVM, while C++ compiles to native code for one platform.
- Java has no operator overloading (apart from
+on strings, which is built in). - Java allows single inheritance of classes, with multiple inheritance only through interfaces.
- Threads, networking and documentation comments (Javadoc) are part of the standard platform.
- Everything lives inside a class. There are no global functions or variables.
Q5. What counts as a statement in Java, and what kinds are there?
A statement is one complete instruction that the program executes. Some expressions become statements just by adding a semicolon: assignments (x = 5;), increments and decrements (i++;), method calls (list.clear();) and object creation (new Thread(task).start();). These are called expression statements. Something like a + b; on its own will not compile, because it does nothing.
The other kinds are declaration statements (int count = 0;) and control flow statements such as if, for, while, switch, break, continue, return and throw. Recent Java also has yield, used to return a value from a block inside a switch expression (Java 14).
Q6. What is a JAR file and why do we use it?
A JAR (Java ARchive) is a ZIP file that bundles compiled .class files with resources like images, property files and a META-INF/MANIFEST.MF file. Originally it was used to download applet code in one request instead of many. That use is gone, since applets are dead.
Today a JAR is how you ship a library or an application. If the manifest names a Main-Class, you can run it with java -jar app.jar. Spring Boot builds "fat" JARs with all dependencies inside, and since Java 9 a JAR with a module-info.class is a modular JAR.
Q7. What is JNI, and when would you use it?
The Java Native Interface lets Java code call functions written in C or C++ (and lets native code call back into Java). You declare a method with the native keyword, and its body lives in a compiled native library loaded with System.loadLibrary.
People use it to reuse an existing native library, to reach OS features Java does not expose, or for hardware access. The costs are real: you lose platform independence, a crash in native code takes down the whole JVM, debugging is harder and you have to write glue code in C. Since Java 22 the Foreign Function and Memory API (java.lang.foreign) is the modern replacement, and it lets you call native functions without writing any C glue.
Q8. What is serialization in Java?
Serialization turns an object (and the objects it refers to) into a stream of bytes, so you can save it to a file or send it over a network. Deserialization rebuilds the object from those bytes. The class must implement java.io.Serializable, and you write with ObjectOutputStream.writeObject and read with ObjectInputStream.readObject. Declare a serialVersionUID so that small class changes do not break old data.
In real projects today, built-in serialization is used much less. Deserializing untrusted bytes has caused many security holes, so Java 9 added serialization filters, and most systems send JSON (Jackson, Gson) or Protocol Buffers instead. Records (Java 16) serialize more safely because they are rebuilt through their canonical constructor.
Q9. Why does Java have empty interfaces with no methods? Name a few.
An interface with no methods is called a marker interface. It adds no behaviour. It only tags a class so that some code can check obj instanceof Serializable and treat it differently. Common ones are Serializable, Cloneable, java.rmi.Remote and java.util.RandomAccess.
For new code, annotations usually do this job better, because they can carry values and be read by frameworks. Marker interfaces still have one advantage: the compiler can check them as a type, for example a method parameter typed Serializable.
Q10. Is synchronized a modifier or an identifier? What does it do?
synchronized is a reserved keyword, so it can never be an identifier. You use it in two ways: as a modifier on a method, or as a block, synchronized (lockObject) { ... }. A thread must hold the object's monitor lock before entering. For an instance method that lock is this, and for a static method it is the class's Class object.
Only one thread can hold a given lock at a time, so the code inside runs one thread at a time and its changes are visible to the next thread that takes the same lock. In Java 21 a virtual thread inside a synchronized block could get pinned to its carrier thread. Java 24 fixed most of that, so synchronized is fine with virtual threads in current releases.
Q11. What is a singleton class and where is it useful?
A singleton is a class that allows exactly one instance in the JVM and gives a global way to reach it. The classic version has a private constructor, a private static field holding the instance and a public static getInstance() method. It suits things where one shared object makes sense: app configuration, a cache, a logger, a connection pool manager.
The simplest correct version today is an enum with one constant. The JVM guarantees one instance, it is thread safe without extra code, and it survives serialization and reflection tricks that break the classic version.
enum AppConfig {
INSTANCE;
String env = "prod";
}
public class SingletonDemo {
public static void main(String[] args) {
AppConfig a = AppConfig.INSTANCE;
AppConfig b = AppConfig.INSTANCE;
System.out.println(a == b);
System.out.println(a.env);
}
}
true
prod
Mention one honest downside: singletons are global state, which makes unit testing harder. In Spring you rarely write one by hand, because beans are singletons by default.
Q12. What is a compilation unit in Java?
It is the term the Java Language Specification uses for one source file that the compiler handles, normally a .java file. It can have an optional package declaration, then import statements, then type declarations (classes, interfaces, enums, records). At most one top-level type can be public, and the file must be named after it.
module-info.java is a special kind called a modular compilation unit. Java 25 also allows compact source files, where a file can contain just a void main() method without a class around it, which is handy for beginners and scripts.
Q13. Is String one of the wrapper classes?
No. The eight wrapper classes are Byte, Short, Integer, Long, Float, Double, Character and Boolean, one for each primitive type. They exist so a primitive value can be treated as an object, for example to store it in a List. Autoboxing converts between the two for you.
String is an ordinary final class that holds a sequence of characters. It is immutable like the wrappers, and string literals get special treatment (the string pool), but it does not wrap any primitive type.
Q14. Why do people say Java is not 100 percent object oriented?
Mainly because of the eight primitive types. An int or a double is a plain value, not an object, so it has no methods and cannot be stored in a collection without boxing. Static methods and fields are a second reason, since they belong to the class and not to any object.
The primitives were kept on purpose, for speed and low memory use. It is a fair point to add that Project Valhalla is working on value classes so that this gap gets smaller, but that work has not shipped as a final feature yet.
Q15. Why doesn't Java allow a class to extend more than one class?
The designers wanted a simpler language than C++, and multiple inheritance of classes brings the diamond problem. If classes B and C both extend A and override the same method, and D extends both, which version does D get? Which copy of A's fields does it hold? C++ answers this with virtual inheritance and extra rules. Java avoided the whole issue.
Java does allow multiple inheritance of type through interfaces. Since default methods arrived in Java 8, a class can inherit two methods with the same signature. In that case the compiler forces the class to override it and pick, using InterfaceName.super.method().
interface Walker { default String move() { return "walk"; } }
interface Swimmer { default String move() { return "swim"; } }
class Duck implements Walker, Swimmer {
@Override
public String move() {
return Walker.super.move() + " and " + Swimmer.super.move();
}
}
public class DiamondDemo {
public static void main(String[] args) {
System.out.println(new Duck().move());
}
}
walk and swim
Quick revision
- Abstract class: state, constructors, one per class. Interface: no state, many per class, default methods since Java 8.
- Checked exceptions must be caught or declared;
RuntimeExceptionsubclasses need not be;Erroris a separate branch. - A custom exception is just a class extending
ExceptionorRuntimeExceptionwith a message constructor. - Marker interfaces tag a class; annotations do the same job in most new code.
- An enum with one constant is the easiest thread-safe singleton.
- No multiple class inheritance because of the diamond problem; interface default method clashes must be overridden.
Frequently asked questions
Do I still need to know Java 8 answers if the company uses Java 21?
Yes, because many interviewers learnt Java with the older rules and will ask the classic question. Give the classic answer first, then add what changed (default methods, records, enum singletons). That shows you know both.
How deep should I go on serialization for a fresher interview?
Know what Serializable, transient and serialVersionUID do, and be ready to say why most services now use JSON instead. Custom writeObject/readObject methods are rarely asked of freshers.
Which of these questions come up most often?
Abstract class versus interface and checked versus unchecked exceptions come up in nearly every round. Practise them with a small code example you can write on paper in under two minutes.
Comments
Post a Comment