Generics in Java

The Java Engineer
By -
0

1. What are Generics in Java?

Answer: Generics in Java are a feature that allows you to create classes, interfaces, and methods with type parameters. This enables type safety by allowing the compiler to enforce type checks at compile time, reducing the risk of ClassCastException at runtime.

2. What are the benefits of using Generics in Java?

Answer:

  • Type Safety: Ensures that you use the correct types, preventing ClassCastException.
  • Code Reusability: Allows the creation of generic algorithms and data structures that can operate on objects of various types.
  • Elimination of Casts: Reduces the need for casting, making the code cleaner and easier to read.

3. Can you provide an example of a generic class?

Answer:


class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
}

// Generic Box class with additional attributes
public class Box<T> {
    private T item;
    private String label;
    private int size;

    // Constructor
    public Box(String label, int size) {
        this.label = label;
        this.size = size;
    }

    // Getter and setter for item
    public void setItem(T item) {
        this.item = item;
    }

    public T getItem() {
        return item;
    }

    // Getter and setter for label
    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    // Getter and setter for size
    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    public static void main(String[] args) {
        // Using Box with String
        Box<String> stringBox = new Box<>("StringBox", 10);
        stringBox.setItem("Hello");
        System.out.println("Label: " + stringBox.getLabel());
        System.out.println("Size: " + stringBox.getSize());
        System.out.println("Item: " + stringBox.getItem());

        // Using Box with Integer
        Box<Integer> intBox = new Box<>("IntBox", 20);
        intBox.setItem(123);
        System.out.println("Label: " + intBox.getLabel());
        System.out.println("Size: " + intBox.getSize());
        System.out.println("Item: " + intBox.getItem());

        // Using Box with custom object Person
        Box<Person> personBox = new Box<>("PersonBox", 30);
        Person person = new Person("Alice", 30);
        personBox.setItem(person);
        System.out.println("Label: " + personBox.getLabel());
        System.out.println("Size: " + personBox.getSize());
        System.out.println("Item: " + personBox.getItem());
    }
}

4. What is a bounded type parameter in Generics?

Answer: A bounded type parameter allows you to restrict the types that can be used as arguments for a type parameter. You can specify an upper bound or a lower bound.

  • Upper Bound:

    public <T extends Number> void printNumber(T number) {
        System.out.println(number);
    }
    
  • Lower Bound:

    public void addNumber(List<? super Integer> list) {
        list.add(123);
    }
    

5. What is the difference between List<Object> and List<?>?

Answer:

  • List<Object>: A list that can contain any type of object. You can add any object to this list.
  • List<?>: A list of unknown type. It is a wildcard and means the list can hold elements of any type, but you cannot add elements to this list except for null.
    • List<?> unknownList = ...;
    • Object element = unknownList.get(0);  // This is safe
      • unknownList.add(null);  // This is allowed
      • unknownList.add("Hello");  // Compile-time error
      • unknownList.add(123);  // Compile-time error

6. Explain wildcards in Java Generics and their types.

Answer: Wildcards are used in Java Generics to represent an unknown type. There are three types of wildcards:

  • Unbounded Wildcard (<?>): Represents an unknown type.
    List<?> list = new ArrayList<String>();
    
  • Upper Bounded Wildcard (<? extends T>): Represents a type that is a subtype of T.
    public void printNumbers(List<? extends Number> list) {
        for (Number number : list) {
            System.out.println(number);
        }
    }
    
  • Lower Bounded Wildcard (<? super T>): Represents a type that is a supertype of T.
    public void addNumbers(List<? super Integer> list) {
        list.add(123);
    }
    

7. Can you provide an example of a generic method?

Answer: Generic methods are methods that introduce their own type parameters. This is similar to declaring a generic type, but the type parameter's scope is limited to the method where it is declared. The scope of the type variable is local to the method itself. it may appear in the method signature and the method body, but not outside the method. A generic method can appear in a class which itself is not generic. The syntax for a generic method includes a list of type parameters, inside angle brackets, which appears before the method's return type. Below is an example of a generic method.

public class GenericMethodExample {
    public static <T> void printArray(T[] array) {
        for (T element : array) {
            System.out.println(element);
        }
    }

    public static void main(String[] args) {
        Integer[] intArray = {1, 2, 3};
        String[] stringArray = {"Hello", "World"};

        printArray(intArray);
        printArray(stringArray);
    }
}

8. What is type erasure in Java Generics?

Answer: Type erasure is a process by which the Java compiler removes all type information during the compilation of a generic class or method. This means that the generic type information is not available at runtime. The compiler replaces type parameters with their bounds or Object if the type parameter is unbounded.

9. Can you overload a method with different generic type parameters?

Answer: No, you cannot overload a method solely based on different generic type parameters because of type erasure. For example:

public class GenericOverloadExample {
    // This will cause a compile-time error
    public void print(List<String> list) {}
    public void print(List<Integer> list) {}
}

10. What are the limitations of Generics in Java?

Answer:

  • Type Erasure: Generic type information is erased at runtime, which can lead to limitations such as the inability to use instanceof with generic types.
  • Primitive Types: Generics do not work with primitive types directly. You need to use their wrapper classes.
  • Static Fields: You cannot create static fields of type parameters.
  • Exceptions: You cannot create instances of generic types or throw/catch generic exceptions.

11. Can you provide an example of a generic interface?

Answer:

public interface GenericInterface<T> {
    void performAction(T t);
}

class StringAction implements GenericInterface<String> {
    @Override
    public void performAction(String s) {
        System.out.println("Action on: " + s);
    }
}

class IntegerAction implements GenericInterface<Integer> {
    @Override
    public void performAction(Integer i) {
        System.out.println("Action on: " + i);
    }
}

public class Main {
    public static void main(String[] args) {
        GenericInterface<String> stringAction = new StringAction();
        stringAction.performAction("Hello");

        GenericInterface<Integer> integerAction = new IntegerAction();
        integerAction.performAction(123);
    }
}

12. How do you create a generic singleton in Java?

Answer: Creating a generic singleton involves ensuring type safety while instantiating a singleton instance.

public class GenericSingleton<T> {
    private static final GenericSingleton<?> INSTANCE = new GenericSingleton<>();

    private GenericSingleton() {}

    @SuppressWarnings("unchecked")
    public static <T> GenericSingleton<T> getInstance() {
        return (GenericSingleton<T>) INSTANCE;
    }
}

public class Main {
    public static void main(String[] args) {
        GenericSingleton<String> stringInstance = GenericSingleton.getInstance();
        GenericSingleton<Integer> integerInstance = GenericSingleton.getInstance();

        System.out.println(stringInstance == integerInstance); // true, same instance
    }
}

13. What is a type parameter?

Answer: The E in the generic class LinkedList<E> is called a type parameter. By convention, type parameter names are single, uppercase letters. The most commonly used type parameter names are:

E - Element (used extensively by the Java Collections Framework)

K - Key

N - Number

T - Type

V - Value

S, U, V - 2nd, 3rd, 4th types

https://www.youtube.com/watch?v=K1iu1kXkVoA&ab_channel=CodingwithJohn

14. What is the unchecked or unsafe operations warning?

Answer: The term "unchecked" means that the compiler does not have enough type information to perform all type checks necessary to ensure type safety. The "unchecked" warning is disabled by default, though the compiler gives a hint. To see all "unchecked" warnings recompile with -Xlint:unchecked. Usually, this warning shows up as follows:

Note: yourFile.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

These warnings are usually encountered when mixing legacy code (before generics) with generic code




Post a Comment

0Comments

Post a Comment (0)

#buttons=(Ok, Go it!) #days=(20)

Our website uses cookies to enhance your experience. Learn more
Ok, Go it!