Java MCQs multiple-choice questions with answers & explanations
All 20 Java quiz questions on one page. Pick an answer in your head, then open Show answer to check it and read why. Want a score and a timer? Take them as a quiz instead.
- 1.easy
With default JVM settings, what does this print?
Integer a = 127, b = 127; Integer c = 128, d = 128; System.out.println((a == b) + " " + (c == d));- A
true false - B
true true - C
false false - D
false true
Show answer
Answer: A (
true false)Autoboxing goes through
Integer.valueOf, which must return cached instances for values from -128 to 127, soaandbare the same object. 128 is outside the default cache, socanddare two different objects, and==compares references. Useequalsto compare wrapper values. - A
- 2.hard
What do these string comparisons print?
String a = "ja"; String b = a + "va"; String c = "ja" + "va"; System.out.println((b == "java") + " " + (c == "java"));- A
true true - B
true false - C
false false - D
false true
Show answer
Answer: D (
false true)"ja" + "va"is a compile-time constant expression, so it is folded to"java"and interned:crefers to the pooled literal.ais notfinal, soa + "va"is evaluated at runtime and creates a newString, and==compares references. Declaringaasfinalwould make both comparisonstrue. - A
- 3.mid
Which overload runs when you pass
null, and what is printed?static void print(Object o) { System.out.println("Object"); } static void print(String s) { System.out.println("String"); } print(null);- A
Object - BCompile error: ambiguous call
- C
NullPointerException - D
String
Show answer
Answer: D (
String)nullmatches both overloads, so the compiler picks the most specific one:Stringis a subtype ofObject, soprint(String)wins. If there were also aprint(Integer)overload, neither would be more specific than the other and the call would be an ambiguous compile error. - A
- 4.mid
What does calling the static method through
pprint?class Parent { static String name() { return "Parent"; } } class Child extends Parent { static String name() { return "Child"; } } Parent p = new Child(); System.out.println(p.name());- A
Child - B
Parent - CCompile error
- D
NullPointerException
Show answer
Answer: B (
Parent)Static methods are not overridden:
Child.name()only hidesParent.name(). A static call is bound at compile time using the declared type of the reference,Parent, so it printsParent. Calling a static method through an instance compiles with a warning, and would work even ifpwerenull. - A
- 5.mid
Given
class A { void run() throws IOException {} }, which override inclass B extends Afails to compile?- A
void run() {} - B
void run() throws FileNotFoundException {} - C
void run() throws RuntimeException {} - D
void run() throws Exception {}
Show answer
Answer: D (
void run() throws Exception {})An overriding method may declare fewer or narrower checked exceptions, but not broader ones:
Exceptionis a supertype ofIOException, and code calling through anAreference would not be prepared for it. Declaring nothing, a subclass such asFileNotFoundException, or any unchecked exception is allowed. - A
- 6.easy
What does
System.out.println(f())print?static int f() { try { return 1; } finally { return 2; } }- A
1 - BCompile error: unreachable code
- C
2 - D
1and then2
Show answer
Answer: C (
2)The
finallyblock runs afterreturn 1is evaluated, and areturninsidefinallyreplaces the pending return value, sof()returns 2. The code compiles; javac only warns under-Xlint:finally. Returning fromfinallyis a bad idea because it also silently discards any exception thrown in thetryblock. - A
- 7.hard
What does
f()return?static int f() { int x = 1; try { return x; } finally { x = 2; } }- A
2 - B
1 - CIt does not compile
- D
0
Show answer
Answer: B (
1)When
return xexecutes, the value ofx(1) is evaluated and saved as the return value. Thefinallyblock then changes the local variable, not the saved value, sof()returns 1. Only areturninsidefinallycould change the result. Ifxreferred to a mutable object, changes to that object infinallywould be visible. - A
- 8.easy
In what order are the body, the
close()calls and thefinallyblock printed?record Res(String name) implements AutoCloseable { public void close() { System.out.print("close " + name + " "); } } try (Res a = new Res("a"); Res b = new Res("b")) { System.out.print("body "); } finally { System.out.print("finally"); }- A
body close a close b finally - B
body finally close b close a - C
close a close b body finally - D
body close b close a finally
Show answer
Answer: D (
body close b close a finally)Resources are closed in the reverse order of declaration, so
bcloses beforea. They are closed as soon as thetryblock finishes, before anycatchorfinallyblock of the same statement runs. - A
- 9.mid
A map created with
new HashMap<>()resizes its table once its size exceeds which number?- A12
- B16
- C8
- D64
Show answer
Answer: A (12)
The default capacity is 16 and the default load factor is 0.75, so the threshold is 16 × 0.75 = 12: adding the 13th entry doubles the table to 32 buckets. 8 is the per-bucket treeify threshold and 64 is the minimum table size for treeification; neither triggers a resize.
- 10.mid
What happens when you call
put("k", null)on aConcurrentHashMap<String, String>?- AIt throws
NullPointerException - BIt stores
"k"mapped tonull - CIt removes the existing mapping for
"k" - DThe call is silently ignored
Show answer
Answer: A (It throws
NullPointerException)ConcurrentHashMaprejectsnullkeys and values with aNullPointerException. In a concurrent map,getreturningnullmust unambiguously mean "absent", because you cannot lock the map to callcontainsKeyin between.HashMap, by contrast, allowsnullvalues and onenullkey. - AIt throws
- 11.hard
What happens when this loop removes
"b"from the list?List<String> list = new ArrayList<>(List.of("a", "b", "c")); for (String s : list) { if (s.equals("b")) list.remove(s); } System.out.println(list);- A
ConcurrentModificationException - B
[a, b, c] - C
[a, c] - D
IndexOutOfBoundsException
Show answer
Answer: C (
[a, c])Removing
"b"shrinks the size to 2, and the iterator's cursor is already 2, sohasNext()returns false and the loop ends beforenext()can perform itsmodCountcheck. It prints[a, c]with no exception. Removing"a"instead would throwConcurrentModificationException, which shows why fail-fast checks are best-effort: useremoveIforIterator.remove(). - A
- 12.mid
What size does this
TreeSetreport?Set<String> set = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); set.addAll(List.of("Java", "java", "JAVA", "Kotlin")); System.out.println(set.size());- A
4 - B
3 - C
1 - D
2
Show answer
Answer: D (
2)A
TreeSetdecides whether an element is a duplicate using its comparator, notequals. The case-insensitive comparator returns 0 for "Java", "java" and "JAVA", so only the first is kept, alongside "Kotlin", giving a size of 2. - A
- 13.easy
What does this stream pipeline print?
Stream.of(1, 2, 3, 4) .peek(n -> System.out.print(n + " ")) .filter(n -> n % 2 == 0) .map(n -> n * 10);- ANothing
- B
1 2 3 4 - C
2 4 - D
20 40
Show answer
Answer: A (Nothing)
Intermediate operations such as
peek,filterandmapare lazy: they only build the pipeline. Without a terminal operation liketoList(),forEachorcount(), no element is ever pulled through it, so nothing is printed. - 14.mid
What does this
Optionalcode print?static String fallback() { System.out.print("fallback "); return "default"; } String v = Optional.of("value").orElse(fallback()); System.out.print(v);- A
value - B
fallback value - C
fallback default - D
default
Show answer
Answer: B (
fallback value)orElsetakes an already-computed value, so its argumentfallback()is evaluated beforeorElseruns, printing "fallback " even though theOptionalholds a value. The result is still "value". UseorElseGet(() -> fallback())to compute the default lazily, only when theOptionalis empty. - A
- 15.mid
Which assignment does NOT compile?
List<Integer> ints = new ArrayList<>(); List<? extends Number> a = ints; // line A List<Number> b = ints; // line B List<? super Integer> c = new ArrayList<Number>(); // line C Collection<Integer> d = ints; // line D- ALine A
- BLine B
- CLine C
- DLine D
Show answer
Answer: B (Line B)
Generics are invariant: a
List<Integer>is not aList<Number>, or you could add aDoubleto a list of integers throughb. Line A works because? extends Numberaccepts a list of anyNumbersubtype, line C becauseNumberis a supertype ofInteger, and line D becauseList<Integer>is a subtype ofCollection<Integer>. - 16.hard
Given
List<? extends Number> nums = new ArrayList<Integer>();, which statement compiles?- A
nums.add(1); - B
nums.add((Number) 1); - C
nums.add(null); - D
nums.add(1.5);
Show answer
Answer: C (
nums.add(null);)With
? extends Number, the compiler only knows the list holds some unknown subtype ofNumber, which could beInteger,Doubleor anything else, so it rejects everyaddexceptnull, which is valid for any reference type. Reading is fine: elements come out asNumber. To add integers you would needList<? super Integer>(PECS). - A
- 17.mid
Two threads each call
increment()1,000 times on the sameCounter. What can you say about the final value ofcount?class Counter { private volatile int count = 0; void increment() { count++; } }- AAlways exactly 2000, since the field is volatile
- BIt can exceed 2000 because of reordering
- CAt most 2000, and it may be less
- DAlways exactly 1000
Show answer
Answer: C (At most 2000, and it may be less)
volatileguarantees visibility, butcount++is still three steps: read, add, write. Two threads can read the same value and both write back that value plus one, losing an update, so the total can be lower than 2000 but never higher. UseAtomicInteger.incrementAndGet()or a lock for an atomic increment. - 18.easy
Which workload benefits most from virtual threads (Java 21)?
- AA CPU-bound image filter that uses every core
- BA server with many requests waiting on I/O
- CSorting one large array held in memory
- DA single-threaded batch calculation
Show answer
Answer: B (A server with many requests waiting on I/O)
Virtual threads make blocking cheap: when one waits on I/O, it unmounts from its carrier thread, so you can run huge numbers of concurrent, mostly waiting tasks with simple blocking code. They add no CPU capacity, so CPU-bound work runs no faster than on platform threads.
- 19.hard
What happens when this code is compiled?
static String check(Object o) { return switch (o) { case Integer i -> "int"; case Integer i when i > 10 -> "big int"; default -> "other"; }; }- AIt compiles;
check(42)returns "big int" - BIt compiles;
check(42)returns "int" - CCompile error: the guarded case is dominated
- DCompile error:
defaultis not allowed here
Show answer
Answer: C (Compile error: the guarded case is dominated)
In a pattern
switch, a case label is dominated when an earlier label matches everything it could match.case Integer ialready matches everyInteger, so the guarded case below it could never run, and javac rejects it. Moving the guarded case above the unguarded one fixes it. - AIt compiles;
- 20.easy
Which class loader loads
java.lang.String?- AThe bootstrap class loader
- BThe platform class loader
- CThe application (system) class loader
- DThe thread context class loader
Show answer
Answer: A (The bootstrap class loader)
Core classes in
java.baseare loaded by the bootstrap class loader, which is built into the JVM, soString.class.getClassLoader()returnsnull. Thanks to parent delegation, the application and platform loaders ask their parent first, which stops application code from replacing core classes.