Java Core Concepts — QA
Automation Interview Prep
(Infosys)
1. Constructor
A constructor is a special method that runs automatically when you
create an object. It has the same name as the class, no return type,
and its job is to initialize the object.
Basic Example:
class Car {
String name;
Car(String name) { // constructor
[Link] = name;
}
}
Car c = new Car("Honda"); // constructor runs here
Selenium Context:
class LoginPage {
WebDriver driver;
LoginPage(WebDriver driver) { // constructor injects driver
[Link] = driver;
}
}
LoginPage login = new LoginPage(driver); // driver passed once,
reused everywhere
This is exactly how Page Object Model classes are initialized.
2. Overloading vs Overriding
Overloading: Same method name, different parameters, same
class. Decided at compile time.
Overriding: Same method name, same parameters, child class
replaces parent’s version. Decided at runtime.
Basic Example:
// Overloading
void add(int a, int b) {}
void add(int a, int b, int c) {}
// Overriding
class Animal { void sound() { [Link]("some sound"); } }
class Dog extends Animal { void sound() {
[Link]("bark"); } }
Selenium Context:
// Overloading - different ways to click
void click(WebElement element) { [Link](); }
void click(By locator) { [Link](locator).click(); }
// Overriding - customizing wait behavior
class BasePage {
void waitForPage() { [Link]("generic wait"); }
}
class HomePage extends BasePage {
@Override
void waitForPage() { [Link]("wait for home page
banner"); }
}
3. Interface vs Abstract Class
Interface Abstract Class
100% abstraction (before Java 8) Partial abstraction
Only method declarations (+ Can have both abstract &
default/static since Java 8) concrete methods
Supports multiple inheritance Only single inheritance
Use implements Use extends
Basic Example:
interface Shape { void draw(); }
abstract class Vehicle {
abstract void run();
void horn() { [Link]("beep"); } // concrete method
}
Selenium Context:
interface BasePage {
void waitForPageLoad(); // every page must implement this
}
class LoginPage implements BasePage {
public void waitForPageLoad() { /* wait logic */ }
}
This is why Selenium’s own WebDriver is an interface, and
ChromeDriver implements it.
4. String vs StringBuilder vs StringBuffer
String: Immutable — every change creates a new object.
StringBuilder: Mutable, fast, not thread-safe.
StringBuffer: Mutable, thread-safe (synchronized), slightly
slower.
Basic Example:
String s = "Hello";
s = s + " World"; // creates a NEW string object
StringBuilder sb = new StringBuilder("Hello");
[Link](" World"); // modifies same object
Selenium Context:
StringBuilder xpath = new StringBuilder();
[Link]("//button[text()='")
.append(buttonName)
.append("']");
[Link]([Link]([Link]())).click();
Building dynamic XPaths is a classic use case for StringBuilder
instead of String concatenation in loops.
5. == vs equals()
== compares reference/memory address (for objects) or value
(for primitives).
.equals() compares actual content/value.
Basic Example:
String a = new String("test");
String b = new String("test");
[Link](a == b); // false (different objects)
[Link]([Link](b)); // true (same content)
Selenium Context:
String actualTitle = [Link]();
String expectedTitle = "Login Page";
if ([Link](expectedTitle)) { // ALWAYS use equals for
assertions
[Link]("Title matched");
}
Never use == to compare page text/titles in Selenium — it can give
wrong results.
6. ArrayList vs LinkedList
ArrayList LinkedList
Backed by dynamic array Backed by doubly linked nodes
Fast random access (get by index) Slow random access
Slow insert/delete in middle Fast insert/delete
Basic Example:
List<Integer> list = new ArrayList<>(); // good for frequent reads
List<Integer> linked = new LinkedList<>(); // good for frequent
insert/delete
Selenium Context:
List<WebElement> rows = [Link]([Link]("tr"));
// ArrayList-like behavior: findElements returns a List, usually
accessed by index
for (int i = 0; i < [Link](); i++) {
[Link]([Link](i).getText());
}
findElements() results are best stored/read via ArrayList since you
mostly loop and access by index — rarely insert/delete in the middle.
7. HashMap vs Hashtable
HashMap Hashtable
Not synchronized (not thread-
Synchronized (thread-safe)
safe)
Allows one null key, multiple null
No null key/value allowed
values
Faster Slower
Modern, preferred Legacy class
Basic Example:
Map<String, String> map = new HashMap<>();
[Link]("id", "101");
[Link](null, "unknown"); // allowed
Selenium Context:
Map<String, String> testData = new HashMap<>();
[Link]("username", "testUser1");
[Link]("password", "Pass@123");
[Link]([Link]("user")).sendKeys([Link]("username"));
[Link]([Link]("pass")).sendKeys([Link]("password"));
Very common for storing test data / config values in automation
frameworks.
8. List vs Set vs Map
List: Ordered, allows duplicates.
Set: Unordered (mostly), no duplicates.
Map: Key-value pairs, keys are unique.
Basic Example:
List<Integer> list = [Link](1, 2, 2, 3); // duplicates
allowed
Set<Integer> set = new HashSet<>(list); // becomes {1, 2, 3}
Map<Integer, String> map = new HashMap<>(); // key -> value
Selenium Context:
List<WebElement> links = [Link]([Link]("a")); //
all links, order matters
Set<String> uniqueLinkTexts = new HashSet<>();
for (WebElement link : links) {
[Link]([Link]()); // auto-removes duplicate
link texts
}
Useful when you want to verify there are no duplicate menu
items/links on a page.
9. Checked vs Unchecked Exception
Checked: Checked at compile time. Must be handled (try-catch
or throws). E.g., IOException.
Unchecked: Occurs at runtime, compiler doesn’t force handling.
E.g., NullPointerException, ArithmeticException.
Basic Example:
// Checked
void readFile() throws IOException {
FileReader fr = new FileReader("[Link]");
}
// Unchecked
int a = 10 / 0; // ArithmeticException at runtime
Selenium Context:
try {
[Link]([Link]("submit")).click();
} catch (NoSuchElementException e) { // unchecked exception
[Link]("Element not found: " + [Link]());
}
NoSuchElementException, TimeoutException,
StaleElementReferenceException are all common unchecked exceptions
in Selenium.
10. throw vs throws
throw: Used to actually throw an exception (inside method body).
throws: Used in method signature to declare that a method might
throw an exception.
Basic Example:
void checkAge(int age) throws Exception { // throws - declaration
if (age < 18) {
throw new Exception("Not eligible"); // throw - actual
exception
}
}
Selenium Context:
public void login(String user, String pass) throws Exception {
if ([Link]()) {
throw new Exception("Username cannot be empty");
}
[Link]([Link]("user")).sendKeys(user);
}
11. static Keyword
static means the member belongs to the class, not to individual
objects. Shared across all instances, accessible without creating an
object.
Basic Example:
class Counter {
static int count = 0; // shared by all objects
Counter() { count++; }
}
Selenium Context:
class DriverManager {
static WebDriver driver; // one shared driver instance
static WebDriver getDriver() {
if (driver == null) {
driver = new ChromeDriver();
}
return driver;
}
}
// used anywhere as: [Link]()
This is exactly how frameworks implement a single shared WebDriver
instance across test classes.
12. final Keyword
final variable → value can’t change (constant).
final method → can’t be overridden.
final class → can’t be extended/inherited.
Basic Example:
final int MAX = 100; // constant
final class Utility { } // cannot be extended
Selenium Context:
public class Constants {
public static final String URL = "[Link] // won't
change during test run
public static final int TIMEOUT = 30;
}
// Used as: [Link]([Link]);
Very common for storing config values like URLs, timeouts,
credentials in a Constants class.
13. this vs super
this → refers to the current object.
super → refers to the parent class object (used to call parent
constructor/method).
Basic Example:
class Animal {
Animal() { [Link]("Animal created"); }
}
class Dog extends Animal {
Dog() {
super(); // calls Animal's constructor
[Link]("Dog created");
}
}
Selenium Context:
class BasePage {
WebDriver driver;
BasePage(WebDriver driver) { [Link] = driver; }
}
class LoginPage extends BasePage {
LoginPage(WebDriver driver) {
super(driver); // calls BasePage constructor to set up
driver
}
}
This pattern is used in almost every Page Object class that extends a
BasePage.
14. Access Modifiers
Subclass
Same Same Other
Modifier (diff
Class Package Package
package)
private ✅ ❌ ❌ ❌
default (no
✅ ✅ ❌ ❌
modifier)
protected ✅ ✅ ✅ ❌
public ✅ ✅ ✅ ✅
Basic Example:
public class Demo {
private int secret = 5; // only inside this class
protected int shared = 10; // accessible in subclasses too
}
Selenium Context:
public class LoginPage {
private WebDriver driver; // hidden from outside
(encapsulation)
public LoginPage(WebDriver driver) { [Link] = driver; }
public void login(String user, String pass) { // public -
callable from test class
[Link]([Link]("user")).sendKeys(user);
}
}
Driver and locators are usually private, while action methods (login(),
clickSubmit()) are public so test classes can call them.
15. Why is String Immutable?
Once created, a String object’s value cannot be changed. Any
“modification” actually creates a new object. Reasons: 1. Security —
used in file paths, network connections, DB credentials; if mutable,
values could be changed after validation. 2. String Pool — allows
Java to reuse String literals, saving memory. 3. Thread safety — no
synchronization needed since it can’t change. 4. HashMap keys —
hashcode stays consistent, safe to use as keys.
Basic Example:
String s1 = "Hello";
String s2 = [Link](" World");
[Link](s1); // still "Hello" - original unchanged
Selenium Context:
String baseUrl = "[Link]
String loginUrl = baseUrl + "/login"; // baseUrl remains unchanged,
new string created
[Link](loginUrl);
[Link](baseUrl); // still "[Link]
Ensures your base config URL never accidentally gets corrupted while
building different page URLs.
16. How Does HashMap Work? (Basic)
1. Each key is converted into a hashcode using hashCode().
2. That hashcode decides which bucket (index in internal array) the
entry goes into.
3. If two keys land in the same bucket (collision), they’re stored as a
linked list (or a tree, if too many, since Java 8) at that bucket.
4. On get(key), HashMap calculates hashcode again, jumps directly
to that bucket, then uses equals() to find the exact key.
This is why lookups are very fast — close to O(1) on average.
Basic Example:
Map<String, Integer> map = new HashMap<>();
[Link]("apple", 1); // hashCode("apple") decides bucket
[Link]("banana", 2);
[Link]([Link]("apple")); // fast direct lookup -> 1
Selenium Context:
Map<String, By> locators = new HashMap<>();
[Link]("username", [Link]("user"));
[Link]("password", [Link]("pass"));
[Link]([Link]("username")).sendKeys("test");
// "username" hashcode -> bucket -> quickly fetch the By locator
Used in frameworks to maintain a locator repository accessed by key
names.
17. Can We Override a Static Method?
No. Static methods belong to the class, not the object, so they are
resolved at compile time (not polymorphic). If a child class defines a
static method with the same signature, it’s called method hiding, not
overriding.
Basic Example:
class Parent {
static void show() { [Link]("Parent static"); }
}
class Child extends Parent {
static void show() { [Link]("Child static"); } //
hides, doesn't override
}
Parent p = new Child();
[Link](); // prints "Parent static" - decided by reference type, not
actual object
Selenium Context:
class DriverFactory {
static WebDriver createDriver() { return new ChromeDriver(); }
}
class FirefoxDriverFactory extends DriverFactory {
static WebDriver createDriver() { return new FirefoxDriver(); }
// hiding, not overriding
}
This is exactly why we avoid overriding static utility methods in Page
Factory/driver factory classes — behavior depends on the reference
type, which can cause confusing bugs.
18. Why Is main() Method Static?
Because JVM needs to call main() without creating an object of the
class first. If main() wasn’t static, JVM would need to create an
instance to call it — but to create an instance, a constructor must run,
and JVM has no way to know which constructor/parameters to use. So
main() is static → JVM can call it directly using the class name.
Basic Example:
public class Demo {
public static void main(String[] args) {
[Link]("Program starts here");
}
}
JVM calls this as [Link](args) — no object needed.
Selenium Context:
public class TestRunner {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver(); // object created
only after main() starts
[Link]("[Link]
[Link]();
}
}
This is the entry point pattern in simple Selenium scripts (before
TestNG/JUnit takes over via annotations like @Test).
Quick Tips for the Interview
Always give the “why” behind an answer, not just the definition —
interviewers at Infosys often ask follow-ups like “why would you
use this in your framework?”
Relate every answer back to your Page Object Model /
framework design since you have 3.7 years of automation
experience — this shows practical understanding, not rote
learning.
Be ready for a follow-up coding question on any of these (e.g.,
“write code to remove duplicates using Set” or “reverse a string
using StringBuilder”).
Good luck with your Infosys interview!