Join Regular Classroom : Visit ClassroomTech

JAVA – codewindow.in

Related Topics

JAVA Programming

public static <T extends Number> double sum(List<T> list) {
    double sum = 0.0;
    for (T number : list) {
        sum += number.doubleValue();
    }
    return sum;
}

Here, the type parameter T is bounded by the Number class, which means that T must be a subtype of Number. The sum method can now only be called with a List that contains objects that are subtypes of Number.

A lower bounded type parameter is defined using the super keyword, followed by the lower bound class or interface. This means that the type parameter must be a supertype of the lower bound. For example, the following code declares a generic method that takes a List of objects that are supertypes of Integer:

public static void addIntegers(List<? super Integer> list) {
    list.add(42);
    list.add(new Integer(43));
}

Here, the type parameter is defined using a wildcard with a lower bound of Integer. This means that the List can contain objects that are Integer or any supertype of Integer, such as Object. The addIntegers method can add Integer objects to the List, as well as any other object that is a subtype of Integer.

Type erasure is the process by which the type information is removed from a generic type at runtime. This is done to maintain backward compatibility with code that was written before the introduction of generics in Java. Type inference is the process by which the Java compiler infers the type of a generic method or constructor argument based on the context in which it is used. Type inference was introduced in Java 7 to make it easier to write generic code by reducing the amount of explicit type information that needs to be provided.

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

In this example, the <T> before the return type of the method indicates that the method has a single type parameter named T. The type parameter can be used anywhere in the method’s signature, and in this case, it is used to define the type of the array parameter.

To call this method, you can pass an array of any type as an argument, like this:

Integer[] intArray = { 1, 2, 3, 4, 5 };
printArray(intArray);

String[] stringArray = { "hello", "world" };
printArray(stringArray);

The benefits of using generic methods include:

  • Reusability: By writing code that works with different types, you can reuse the same code for different situations.

  • Type safety: By using generics, you can catch type errors at compile time rather than at runtime.

  • Code clarity: Generics can make your code more readable and maintainable by reducing the need for casting and other type-related boilerplate code.

public class Box<T> {
    private T value;

    public <U extends T> Box(U value) {
        this.value = value;
    }

    public T getValue() {
        return value;
    }
}

In this example, the Box class has a type parameter T, and the constructor also has a type parameter U that extends T. The constructor takes an argument of type U and assigns it to the value field of the Box object.

Here’s how you can use this generic constructor to create a Box object with a specific type:

Box<String> box = new Box<>("Hello, World!");

In this example, we create a Box object with a String value of "Hello, World!". The type parameter T is inferred to be String, and the type parameter U is also String, since String extends Object.

Using a generic constructor can be useful when you want to create a new instance of a generic class, but you don’t know the exact type argument at compile time.

List rawList = new ArrayList(); // raw type
List<String> genericList = new ArrayList<String>(); // generic type

@SuppressWarnings("rawtypes")
List uncheckedList = rawList; // suppress warning for unchecked assignment

@SuppressWarnings("unchecked")
List<String> uncheckedCast = (List<String>) uncheckedList; // suppress warning for unchecked cast

In this example, we are using a raw type with a generic class and performing an unchecked type cast. By using the @SuppressWarnings annotation, we can suppress the warnings generated by the compiler. However, it is important to use this annotation sparingly and only when it is absolutely necessary, as it can mask potential issues in the code.

      

Go through our study material. Your Job is awaiting.

Recent Posts
Categories