Java Interview Question and Answers
Access Control Modifiers:
Java provides a number of access modifiers to set access levels for classes, variables, methods and constructors.
The four access levels are:
- Visible to the package, the default. No modifiers are needed.
- Visible to the class only (private).
- Visible to the world (public).
- Visible to the package and all subclasses (protected).
Non Access Modifiers:
Java provides a number of non-access modifiers to achieve many other functionality.
- The static modifier for creating class methods and variables
- The final modifier for finalizing the implementations of classes, methods, and variables.
- The abstract modifier for creating abstract classes and methods.
- The synchronized and volatile modifiers, which are used for threads.
What final in Java?
Final is the keyword
- final methods can not be override but we can override static methods.
- final classes can not be extended.
- final variables can not be modified.
Can we create static variable in side final method?
we can not create static variables in side final methods.
Example:
public final void simple1(){
static String af="10";//Error:Illegal modifier for parameter af; only final is permitted
String af1="10";
final String af2="10";
}
final class TestSuper {
static String t="20"; // this is allowed
}
Will below code compiles successfully?
- public class Test {
- class T{
- static String af="20";
- }
- }
Answer: NO, compilation Error at line 3 The field af cannot be declared static in a non-static inner type, unless initialized with a constant expression.
Will below code compiles successfully?
- public class Test {
- class T{
- final String af="20";
- }
- }
Answer:YES
Will below code compiles successfully?
- public class Test {
- final class T{
- static String af="20";
- }
- }
Answer: NO, compilation Error at line 3 Error:The field af cannot be declared static in a non-static inner type, unless initialized with a constant expression
Will below code compiles successfully?
- public class Test {
- class T{
- static void ma() {
- }
- }
- }
Answer: NO, compilation Error at line 3 The method ma cannot be declared static; static methods can only be declared in a static or top level type.
Which are true? (Choose all that apply.)
class TestSer {
public static void main(String[] args) {
SpecialSerial s = new SpecialSerial();
try {
ObjectOutputStream os = new ObjectOutputStream(
new FileOutputStream("myFile.txt"));
os.writeObject(s); os.close();
System.out.print(++s.z + " ");
ObjectInputStream is = new ObjectInputStream(
new FileInputStream("myFile.txt"));
SpecialSerial s2 = (SpecialSerial)is.readObject();
is.close();
System.out.println(s2.y + " " + s2.z);
} catch (Exception x) {x.printStackTrace(); }
}
}
class SpecialSerial implements Serializable {
transient int y = 7;
int z = 9;//see the difference
}
A. Compilation fails
B. The output is 10 0 9
C. The output is 10 0 10
D. The output is 10 7 9
E. The output is 10 7 10
F. In order to alter the standard deserialization process you would implement the
readObject() method in SpecialSerial
G. In order to alter the standard deserialization process you would implement the
defaultReadObject() method in SpecialSerial
Answer:B
Question:
import java.io.*;
public class ReadingFor {
public static void main(String[] args) {
String s;
try {
FileReader fr = new FileReader("myfile.txt");
BufferedReader br = new BufferedReader(fr);
while((s = br.readLine()) != null)
System.out.println(s);
br.flush();
} catch (IOException e) { System.out.println("io error"); }
}
}
And given that myfile.txt contains the following two lines of data:
ab
cd
What is the result?
A. ab
B. abcd
C. ab
D. a b c d
E. Compilation fails
Answer:
E is correct. You need to call flush() only when you're writing data. Readers don't have
flush() methods. If not for the call to flush(), answer C would be correct.
If line 6 creates a valid Console object, and if the user enters fred as a username and 1234 as a
password, what is the result? (Choose all that apply.)
import java.io.*;
public class Talker {
public static void main(String[] args) {
Console c = System.console();
String u = c.readLine("%s", "username: ");
System.out.println("hello " + u);
String pw;
if(c != null && (pw = c.readPassword("%s", "password: ")) != null)
// check for valid password
}
}
A. username:
password:
B. username: fred
password:
C. username: fred
password: 1234
D. Compilation fails
E. An exception is thrown at runtime
Answer:
D is correct. The readPassword() method returns a char[]. If a char[] were used,
answer B would be correct.
Instances of which class(es) can be serialized? (Choose all that apply.)
import java.io.*;
class Vehicle { }
class Wheels { }
class Car extends Vehicle implements Serializable { }
class Ford extends Car { }
class Dodge extends Car {
Wheels w = new Wheels();
}
A. Car
B. Ford
C. Dodge
D. Wheels
E. Vehicle
Answer:
A and B are correct. Dodge instances cannot be serialized because they "have" an instance
of Wheels, which is not serializable. Vehicle instances cannot be serialized even though the
subclass Car can be.
Which are true? (Choose all that apply.)
import java.text.*;
public class Slice {
public static void main(String[] args) {
String s = "987.123456";
double d = 987.123456d;
NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(5);
System.out.println(nf.format(d) + " ");
try {
System.out.println(nf.parse(s));
} catch (Exception e) { System.out.println("got exc"); }
}
}
A. The output is 987.12345 987.12345
B. The output is 987.12346 987.12345
C. The output is 987.12345 987.123456
D. The output is 987.12346 987.123456
E. The try/catch block is unnecessary
F. The code compiles and runs without exception
G. The invocation of parse() must be placed within a try/catch block
Answer:
D, F, and G are correct. The setMaximumFractionDigits() applies to the formatting
but not the parsing. The try/catch block is placed appropriately. This one might scare you
into thinking that you'll need to memorize more than you really do. If you can remember
that you're formatting the number and parsing the string you should be fine for the exam.
What is the result?
class Archie {
public static void main(String[] args) {
Pattern p = Pattern.compile("\\d*");
Matcher m = p.matcher("ab2c4d67");
int count = 0;
while(m.find())
count++;
System.out.print(count);
}
}
Answer:8
What is the result?
class Archie {
public static void main(String[] args) {
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher("ab2c4d67");
int count = 0;
while(m.find())
count++;
System.out.print(count);
}
}
Answer:3
What is the result?
import java.util.*;
public class Looking {
public static void main(String[] args) {
String input = "1 2 a 3 45 6";
Scanner sc = new Scanner(input);
int x = 0;
do {
x = sc.nextInt();
System.out.print(x + " ");
} while (x!=0);
}
}
A. 1 2
B. 1 2 3 45 6
C. 1 2 3 4 5 6
D. 1 2 a 3 45 6
E. Compilation fails
F. 1 2 followed by an exception
Answer:
F is correct. The nextXxx() methods are typically invoked after a call to a hasNextXxx(),
which determines whether the next token is of the correct type.
Which statements are true?
public static void before() {
Set set = new TreeSet();
set.add("2");
set.add(3);
set.add("1");
Iterator it = set.iterator();
while (it.hasNext())
System.out.print(it.next() + " ");
}
A. The before() method will print 1 2
B. The before() method will print 1 2 3
C. The before() method will print three numbers, but the order cannot be determined
D. The before() method will not compile
E. The before() method will throw an exception at runtime
Answer:
E is correct. You can't put both Strings and ints into the same TreeSet. Without generics,
the compiler has no way of knowing what type is appropriate for this TreeSet, so it allows
everything to compile. At runtime, the TreeSet will try to sort the elements as they're
added, and when it tries to compare an Integer with a String it will throw a
ClassCastException. Note that although the before() method does not use generics,
it does use autoboxing. Watch out for code that uses some new features and some old
features mixed together.
What is the output of below program?
class MapEQ {
public static void main(String[] args) {
Map<ToDos, String> m = new HashMap<ToDos, String>();
ToDos t1 = new ToDos("Monday");
ToDos t2 = new ToDos("Monday");
ToDos t3 = new ToDos("Tuesday");
m.put(t1, "doLaundry");
m.put(t2, "payBills");
m.put(t3, "cleanAttic");
System.out.println(m.size());
}
}
class ToDos{
String day;
ToDos(String d) { day = d; }
public boolean equals(Object o) {
return ((ToDos)o).day == this.day;
}
public int hashCode() { return 9; }
}
Answer:2
What is the output of below program?
class MapEQ {
public static void main(String[] args) {
Map<ToDos, String> m = new HashMap<ToDos, String>();
ToDos t1 = new ToDos("Monday");
ToDos t2 = new ToDos("Monday");
ToDos t3 = new ToDos("Tuesday");
m.put(t1, "doLaundry");
m.put(t2, "payBills");
m.put(t3, "cleanAttic");
System.out.println(m.size());
}
}
class ToDos{
String day;
ToDos(String d) { day = d; }
public boolean equals(Object o) {
return ((ToDos)o).day == this.day;
}
//public int hashCode() { return 9; }
}
Answer:3
Explanation:If hashCode() is not overridden then every entry will go into its own
bucket, and the overridden equals() method will have no effect on determining equivalency.
If hashCode() is overridden, then the overridden equals() method will view t1 and
t2 as duplicates.
This class is to be updated to make use of appropriate generic types, with no changes in behavior
(for better or worse). Which of these steps could be performed? (Choose three.)
public class AccountManager {
private Map accountTotals = new HashMap();
private int retirementFund;
public int getBalance(String accountName) {
Integer total = (Integer) accountTotals.get(accountName);
if (total == null)
total = Integer.valueOf(0);
return total.intValue();
}
public void setBalance(String accountName, int amount) {
accountTotals.put(accountName, Integer.valueOf(amount));
}
}
A. Replace line 13 with
private Map<String, int> accountTotals = new HashMap<String, int>();
B. Replace line 13 with
private Map<String, Integer> accountTotals = new HashMap<String, Integer>();
C. Replace line 13 with
private Map<String<Integer>> accountTotals = new HashMap<String<Integer>>();
D. Replace lines 17–20 with
int total = accountTotals.get(accountName);
if (total == null) total = 0;
return total;
E. Replace lines 17–20 with
Integer total = accountTotals.get(accountName);
if (total == null) total = 0;
return total;
F. Replace lines 17–20 with
return accountTotals.get(accountName);
G. Replace line 24 with
accountTotals.put(accountName, amount);
H. Replace line 24 with
accountTotals.put(accountName, amount.intValue());
Answer:
B, E, and G are correct.
A is wrong because you can't use a primitive type as a type parameter. C is wrong because
a Map takes two type parameters separated by a comma. D is wrong because an int can't
autobox to a null, and F is wrong because a null can't unbox to 0. H is wrong because you
can't autobox a primitive just by trying to invoke a method with it. (Objective 6.4)
Which of the following changes (taken separately) would allow this code to compile?
(Choose all that apply.)
interface Hungry<E> { void munch(E x); }
interface Carnivore<E extends Animal> extends Hungry<E> {}
interface Herbivore<E extends Plant> extends Hungry<E> {}
abstract class Plant {}
class Grass extends Plant {}
abstract class Animal {}
class Sheep extends Animal implements Herbivore<Sheep> {
public void munch(Sheep x) {}
}
class Wolf extends Animal implements Carnivore<Sheep> {
public void munch(Sheep x) {}
}
A. Change the Carnivore interface to
interface Carnivore<E extends Plant> extends Hungry<E> {}
B. Change the Herbivore interface to
interface Herbivore<E extends Animal> extends Hungry<E> {}
C. Change the Sheep class to
class Sheep extends Animal implements Herbivore<Plant> {
public void munch(Grass x) {}
}
D. Change the Sheep class to
class Sheep extends Plant implements Carnivore<Wolf> {
public void munch(Wolf x) {}
}
E. Change the Wolf class to
class Wolf extends Animal implements Herbivore<Grass> {
public void munch(Grass x) {}
}
F. No changes are necessary
Answer:
B is correct. The problem with the original code is that Sheep tries to implement
Herbivore<Sheep> and Herbivore declares that its type parameter E can be any type that
extends Plant. Since a Sheep is not a Plant, Herbivore<Sheep> makes no sense—
the type Sheep is outside the allowed range of Herbivore's parameter E. Only solutions
that either alter the definition of a Sheep or alter the definition of Herbivore will be able
to fix this. So A, E, and F are eliminated. B works, changing the definition of an Herbivore
to allow it to eat Sheep solves the problem. C doesn't work because an Herbivore<Plant>
must have a munch(Plant) method, not munch(Grass). And D doesn't work, because
in D we made Sheep extend Plant, now the Wolf class breaks because its munch(Sheep)
method no longer fulfills the contract of Carnivore. (Objective 6.4)
What is the output of below program?
class OrderedPair<T, E> {
private T key;
private E value;
public OrderedPair(T key, E value) {
this.key = key;
this.value = value;
}
public T getKey() { return key; }
public E getValue() { return value; }
}
class SlimClass {
public static void main(String args[]) {
OrderedPair orderPair = new OrderedPair(new CC(), "damu");
System.out.println(orderPair.getKey());
System.out.println(orderPair.getValue());
}
Answer:
output:
test.com.CC@12b6651
damu
Why Generics?
- Code that uses generics has many benefits over non-generic code:
- Stronger type checks at compile time.
- A Java compiler applies strong type checking to generic code and issues errors if the code violates type safety. Fixing compile-time errors is easier than fixing runtime errors, which can be difficult to find.
Elimination of casts.
The following code snippet without generics requires casting:
List list = new ArrayList();
list.add("hello");
String s = (String) list.get(0);
When re-written to use generics, the code does not require casting:
List<String> list = new ArrayList<String>();
list.add("hello");
String s = list.get(0); // no cast
Enabling programmers to implement generic algorithms.
Question:
Given a method declared as
public static <E extends Number> List<E> process(List<E> nums)
A programmer wants to use this method like this
// INSERT DECLARATIONS HERE
output = process(input);
Which pairs of declarations could be placed at // INSERT DECLARATIONS HERE to allow
the code to compile? (Choose all that apply.)
A. ArrayList<Integer> input = null;
ArrayList<Integer> output = null;
B. ArrayList<Integer> input = null;
List<Integer> output = null;
C. ArrayList<Integer> input = null;
List<Number> output = null;
D. List<Number> input = null;
ArrayList<Integer> output = null;
E. List<Number> input = null;
List<Number> output = null;
F. List<Integer> input = null;
List<Integer> output = null;
G. None of the above
Answer:
B, E, and F are correct.
The return type of process is definitely declared as a List, not an ArrayList, so A and D
are wrong. C is wrong because the return type evaluates to List<Integer>, and that can't
be assigned to a variable of type List<Number>. Of course all these would probably cause a
NullPointerException since the variables are still null—but the question only asked us
to get the code to compile.
Also see: