Generics in Java Created 2026-10-13 Updated 2026-11-05
Generics in Java parameterize classes, interfaces and methods by reference types so reusable code can retain compile-time type checks. For example, List<String> describes a list whose elements are strings, and retrieving one has static type String. Java generic types are generally invariant: List<Integer> is not a subtype of List<Number>. Wildcards express related producer or consumer views. Type erasure means a parameterized class usually has one shared runtime class rather than a fresh class for each type argument. Primitive values use wrapper types in ordinary generic collections.[ref]
// Target: computer-science.bigb
Java (programming language) Created 2026-10-13 Updated 2026-11-05
Java is a class-based, statically typed programming language whose ordinary implementation compiles source into bytecode for a Java virtual machine. Its type system, exception rules and object model specify program behaviour; the virtual machine supplies execution and managed storage. Generics in Java add parameterized types checked largely at compilation, with type erasure shaping their runtime representation. The Java language, the virtual-machine specification and a particular vendor's development kit are separate layers, so an implementation detail should not be mistaken for a universal language rule.[ref]
// Target: computer-science.bigb
A collections library can supply a genuinely generic method in Java whose own type parameter connects the input element and the result element type:
java
static <T> java.util.List<T> oneElement(T item) {
    java.util.List<T> result = new java.util.ArrayList<T>();
    result.add(item);
    return result;
}
For example, List<String> xs = oneElement("sample"); is type-checked without a cast. The method can also construct a List<Integer> from an integer object. The standard library's Collections.singletonList is another example of this type relationship, though its returned list is unmodifiable.
The benefit is one reusable implementation with compile-time argument/result consistency. A raw List result would lose element-type information, invite unchecked calls and require casts that may fail later. Separate methods for every element type would duplicate code. Merely enclosing a concrete type in angle brackets, such as returning List<String>, does not make a method generic; the method here declares <T>. Type erasure means the guarantee is primarily a source-level type check, not a distinct runtime class for each type argument.
Replace type parameters by their erasures, normally Object or the first declared bound, and insert checked casts where an erased result is used as its former specific type. A simple generics in Java example becomes:
// Generic version
Vector<String> names = new Vector<String>();
names.add("Ada");
String s = names.get(0);

// Non-generic version
Vector names = new Vector();
names.add("Ada");
String s = (String) names.get(0);
The two fragments are alternatives, not consecutive declarations in one scope. For a user-defined Box<T>, replace fields, parameters and returns of type T by Object, and cast the retrieved result. Bounded parameters instead erase to their bound. A full translation must also preserve method dispatch where erasure changes overridden signatures, using suitable forwarding methods; this is the principle of type erasure, not simply deleting every pair of angle brackets.
The raw collection permits accidental insertion of an unrelated object, which may fail much later at a cast. The generic collection rejects such insertion during compilation, documents its contract at the declaration, and eliminates repetitive casts at use sites. The generic version catches more errors earlier and expresses the programmer's intended element type directly. Generic types are largely erased at runtime, so their advantage is static checking rather than a new runtime vector representation. The translation mechanism is specified by the Java language specification.
The output is 1, with no newline. The Any in class B[Any] and class C[Any] is a type parameter name that shadows the standard type scala.Any inside those class bodies. Renaming it to T preserves the program's meaning. Thus new B[Int] has an inherited m(Double) and its own m(Int); obj1.m(1) selects the latter and prints 1. The call with 2.3 can only use the inherited m(Double), which computes a sum without printing.
For new C[Any], the supplied type argument is the standard scala.Any, so the overloads are m(Double) and m(scala.Any). The more-specific Double alternative accepts 4 by numeric widening, and accepts 5.6 directly. Both return sums without printing. A computed result is not automatically screen output. This reasoning uses the Scala 2.11 overload conventions of Question 5(a); type erasure does not turn either class's generic-argument overload into an method overriding of m(Double).
Type erasure Created 2026-10-14 Updated 2026-11-05
In Java, type erasure implements generic code by replacing a type parameter with its bound, or Object if unbounded, while inserting required casts and bridge methods. Thus List<String> and List<Integer> share a runtime list class even though the compiler checks different element types. Some generic type information remains in metadata for reflection, so erasure does not mean every trace of generic declarations disappears. Restrictions such as the inability to directly create new T() follow from the absence of a distinct reified runtime class for arbitrary type arguments.[ref]
// Target: computer-science.bigb