Java for Selenium

Selenium interviews test Java as much as Selenium. These are the Java topics that come up most for automation testers — collections in a framework, immutable classes, final vs finally vs finalize, abstract classes vs interfaces, overloading, string comparison and checking sort order — each tied to where it appears in real Selenium code. The pure-Java examples were compiled and run; the outputs are real.

Advertisement

Collections in an Automation Framework

Collection Where you'll use it in Selenium
List / ArrayList findElements() returns List<WebElement>; table rows, dropdown options, test data rows
Set getWindowHandles() returns Set<String> because handles are unique; de-duplicating values
Map / HashMap Configuration (browser, base URL), test data records, expected values by key
List<Map<String, String>> Data-driven testing: each map is one row from Excel or JSON
Map<String, String> config = new HashMap<>();
config.put("browser", "chrome");
config.put("baseUrl", "https://qa.example.com");
config.get("browser");                        // "chrome"
config.getOrDefault("timeout", "10");         // "10" — no timeout key yet

Set<String> handles = new LinkedHashSet<>(List.of("CDwindow-A", "CDwindow-B", "CDwindow-A"));
// [CDwindow-A, CDwindow-B] — duplicates removed

A Properties object (which is itself a key–value table) is the usual way to load a .properties file; many frameworks then copy values into a Map. Full comparison: List vs Set vs Map and Collections in Your Framework.

Making a Class Immutable

An immutable object can't change after it's created — useful for test data and configuration shared across parallel threads, because nothing can modify it unexpectedly.

The rules

  1. Declare the class final so it can't be subclassed.
  2. Make all fields private final.
  3. Set everything in the constructor; provide no setters.
  4. Copy mutable inputs (lists, arrays, dates) when storing them.
  5. Don't hand out mutable internals — return copies or unmodifiable views.
public final class TestUser {
    private final String username;
    private final String role;
    private final List<String> permissions;

    public TestUser(String username, String role, List<String> permissions) {
        this.username = username;
        this.role = role;
        this.permissions = List.copyOf(permissions);   // defensive, unmodifiable copy
    }

    public String getUsername()          { return username; }
    public String getRole()              { return role; }
    public List<String> getPermissions() { return permissions; }   // already unmodifiable

    public TestUser withRole(String newRole) {                     // "changing" creates a new object
        return new TestUser(username, newRole, permissions);
    }
}

What happens when you try to change it:

List<String> perms = new ArrayList<>(List.of("read", "write"));
TestUser user = new TestUser("asha", "tester", perms);
perms.add("delete");                      → user.getPermissions() is still [read, write]
user.getPermissions().add("admin");       → UnsupportedOperationException
user.withRole("admin")                    → a new object; user's role is still "tester"

String is the best-known immutable class in Java. On Java 16+, a record gives you final fields, a constructor and getters automatically (you still need to copy mutable fields).

final vs finally vs finalize

  What it is Example
final Keyword: a final variable can't be reassigned, a final method can't be overridden, a final class can't be extended private static final int TIMEOUT = 10;
finally Block after try/catch that always runs Closing a file or JDBC connection
finalize() Old method the garbage collector might call before reclaiming an object Deprecated — don't use it

finalize() has been deprecated since Java 9 and is marked for removal, because there's no guarantee when — or whether — it runs. For cleanup, use try-with-resources or finally. In test code, closing the browser belongs in @AfterMethod(alwaysRun = true), not in a finally inside each test.

Abstract Class vs Interface

Abstract class Interface
Abstract and concrete methods Abstract methods, plus default and static methods (Java 8) and private methods (Java 9)
Instance fields of any kind, and constructors Only public static final constants; no constructors
A class can extend only one A class can implement many
"Is-a" with shared code and state A contract — "can do"

In Selenium: WebDriver, WebElement, JavascriptExecutor and TakesScreenshot are interfaces; ChromeDriver implements several of them through RemoteWebDriver. In your framework, a BasePage is often an abstract class holding the driver and shared wait helpers.

Can an abstract class have no abstract methods?

Yes. An abstract class can contain only concrete methods — it just can't be instantiated. Any concrete subclass must implement the abstract methods it does have.

Multiple Inheritance and the Diamond Problem

Java doesn't allow a class to extend two classes: if both parents had the same method, which one should the child inherit? That ambiguity is the diamond problem. A class can implement several interfaces instead — and if two interfaces supply the same default method, the class must override it and choose explicitly.

WebDriver driver = new ChromeDriver();
((JavascriptExecutor) driver).executeScript("window.scrollBy(0, 500)");   // same object, another interface
((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);

Method Overloading in Selenium

Same method name, different parameter lists — resolved at compile time. Selenium's own API is full of it:

driver.switchTo().frame(0);                 // by index
driver.switchTo().frame("paymentFrame");    // by name or id
driver.switchTo().frame(frameElement);      // by WebElement

// Your own utilities
public void enterText(WebElement element, String text) { element.clear(); element.sendKeys(text); }
public void enterText(By locator, String text)          { enterText(driver.findElement(locator), text); }

Overriding is the runtime counterpart: a subclass redefines a parent method with the same signature — for example a page class overriding isLoaded() from BasePage. More: OOP Concepts in Your Framework.

Comparing Strings

String a = "Welcome";
String b = new String("Welcome");
a == b                          → false  (different objects)
a.equals(b)                     → true   (same content)
"WELCOME".equalsIgnoreCase(a)   → true
" Welcome ".equals(a)           → false
" Welcome ".trim().equals(a)    → true
  • Never use == for string content — it compares references.
  • getText() often includes extra spaces or line breaks; trim() (or strip()) before comparing.
  • In tests, prefer Assert.assertEquals(actual, expected) over if (equals) — it fails the test and shows both values.

Verifying a List Is Sorted

A classic Selenium task: after clicking "Sort by price", confirm the prices are in ascending order.

List<String> texts = driver.findElements(By.cssSelector(".price"))
        .stream().map(WebElement::getText).toList();      // e.g. ["₹ 499", "₹ 1,299", "₹ 2,499"]

static List<Integer> parsePrices(List<String> texts) {
    List<Integer> out = new ArrayList<>();
    for (String t : texts) out.add(Integer.parseInt(t.replaceAll("[^0-9]", "")));   // strip ₹, commas, spaces
    return out;
}

static boolean isSortedAscending(List<Integer> values) {
    for (int i = 1; i < values.size(); i++)
        if (values.get(i) < values.get(i - 1)) return false;
    return true;
}

// parsePrices → [499, 1299, 2499], isSortedAscending → true
// isSortedAscending([10, 5, 20]) → false

// Alternative: compare with a sorted copy
List<Integer> copy = new ArrayList<>(prices);
Collections.sort(copy);
Assert.assertEquals(prices, copy);

Parse to numbers before comparing — sorting the strings "1,299" and "499" as text gives the wrong order. See how the element lookups in this example run in the browser in the Selenium WebDriver Visualizer.

From Real Projects

In my automation roles I created, modified and enhanced Selenium WebDriver scripts in Java, organized with POM classes and a business library, and ran them with TestNG on Chrome and Firefox. Exercises like these build exactly the muscle memory you need when a real application — for me, Canolog's sales, inventory and service screens — throws a new kind of element at you. Lists of WebElements and maps of test data are where collections show up first in a framework.

📚 Official documentation: Oracle Java Tutorials: Collections · dev.java: Learn Java (Oracle)

FAQs

Which collections do you use in a Selenium framework?

List for elements and data rows, Set for window handles and unique values, Map for configuration and test data, and List<Map<String, String>> for data-driven tests.

How do you make a class immutable?

Make the class final and its fields private final, set them only in the constructor, provide no setters, copy mutable inputs and never expose mutable internals.

final vs finally vs finalize?

final prevents reassignment, overriding or inheritance; finally always runs after try/catch; finalize() is a deprecated garbage-collector hook you shouldn't use.

Abstract class vs interface?

An abstract class can hold state, constructors and concrete methods, and a class can extend only one; an interface defines a contract, and a class can implement many.

Why does Java not allow multiple inheritance of classes?

To avoid the diamond problem — ambiguity when two parents define the same method. Multiple interfaces are allowed instead.

Where does overloading appear in Selenium?

switchTo().frame(int | String | WebElement), findElement variants in utilities, and your own overloaded helpers.