public class Box<T> { private T content; public void setContent(T content) { this.content = content; } public T getContent() { return content; } }Java Generic Type Naming convention helps us understanding code easily and having a naming convention is one of the best practices of Java programming language. So generics also comes with its own naming conventions. Usually, type parameter names are single, uppercase letters to make it easily distinguishable from java variables. The most commonly used type parameter names are: E – Element (used extensively by the Java Collections Framework, for example ArrayList, Set etc.) K – Key (Used in Map) N – Number T – Type V – Value (Used in Map) S,U,V etc. – 2nd, 3rd, 4th types// Generic method example 1 <T> void fromArrayToCollection(T[] a, Collection<T> c){ for (T o: a){ c.add(o); } } // Generic method example 2 public static <T extends SomeClass & SomeInterface> methodName(T o){ o.setterMethod(123); } // Generic method example 3 public static <T> Stack <T> loadFromArray(Object[] arr, Class<T> type){ Stack <T> stack = new StackArray<>(arr.length); for (Object o:arr){ if (type.isInstance(o)){ stack.push( (T) o); // type checking with "isInstance" and casting. "instanceof" will not work here. } } } <Car> c = loadFromArray(object_arr_of_cars, Car.class); // generic methods public <T> List<T> fromArrayToList(T[] a) { return Arrays.stream(a).collect(Collectors.toList()); } public static <T, G> List<G> fromArrayToList(T[] a, Function<T, G> mapperFunction) { return Arrays.stream(a) .map(mapperFunction) .collect(Collectors.toList()); } // bounded generics public <T extends Number> List<T> fromArrayToList(T[] a) { ... } //multiple bounds <T extends Number & Comparable> // upper bound wildcards public static void paintAllBuildings(List<? extends Building> buildings) { ... } // lower bound wildcard <? super T>public class Tuple <T> { // the T is a placeholder for any datatype public T leftValue; public T rightValue; public Tuple(T leftValue, T rightValue){ // again, T is being used as a placeholder for any type this.leftValue = leftValue; this.rightValue = rightValue; } public class Program{ public static void main (String args){ // And upon using Tuples we can fill in the T from the Tuple class with actual datatypes Tuple <int> intTuple = new Tuple <int>(5, 500) Tuple <String> stringTuple = new Tuple <String> ("Hello", "World") // we can even put Tuples inside of Tuples! Tuple<Tuple<int>> metaIntTuple = new Tuple <Tuple <int>> (intTuple, new Tuple <int> (456, 0)); } }public <T> List<T> fromArrayToList(T[] a) { return Arrays.stream(a).collect(Collectors.toList()); }public class GenericFunction { public static void main(String[] args) { Integer[] intArray = {1,2,3,4,5,6,7}; Double[] doubleArray = {1.1,2.2,3.3,4.4,5.0}; Character[] charArray = {'a' , 'b' , 'c' , 'd' , 'e'}; System.out.println("Integer Array :"); genericFunction(intArray); System.out.println(); System.out.println("Double Array : "); genericFunction(doubleArray); System.out.println(); System.out.println("Character Array : "); genericFunction(charArray); } // Generic Function In Java public static <T> void genericFunction(T[] nums){ for(T element : nums){ System.out.print(element + " "); } } } // Generic interface interface BoxInterface<T> { void setValue(T value); T getValue(); } // Generic class implementing the BoxInterface with T class Box<T> implements BoxInterface<T> { private T value; @Override public void setValue(T value) { this.value = value; } @Override public T getValue() { return value; } } public class Main { public static void main(String[] args) { // Using T Box<String> stringBox = new Box<>(); stringBox.setValue("Hello, Generics!"); String stringValue = stringBox.getValue(); // Using ? (wildcard) with Interface BoxInterface<?> wildcardBox = stringBox; // wildcardBox.setValue("This won't compile"); // We cannot set value of unknown type Object wildcardValue = wildcardBox.getValue(); // We can only cast value to Object type // Using ? extends T (upper bounded wildcard) with Interface // Focus type : the type on the right side of extend BoxInterface<? extends String> upperBoundedWildcardBox = stringBox; // upperBoundedWildcardBox.setValue("This won't compile"); // We cannot set value of unknown type String upperBoundedWildcardValue = upperBoundedWildcardBox.getValue(); // We can only cast value to Parent type, String in this case // Using ? super T (loower bounded wildcard) with Interface // Focus type : the type on the left side of super BoxInterface<? super String> lowerBoundedWildcardBox = new Box<>(); lowerBoundedWildcardBox.setValue("Lower Bounded Wildcard"); // We can set value to parent type, String in this case Object lowerBoundedWildcardValue = lowerBoundedWildcardBox.getValue(); // We can only cast value to Parent type, Object in this case } }