{"id":2437,"date":"2020-10-10T13:56:38","date_gmt":"2020-10-10T13:56:38","guid":{"rendered":"https:\/\/system.camp\/?p=2437"},"modified":"2020-10-12T05:32:37","modified_gmt":"2020-10-12T05:32:37","slug":"java-generics","status":"publish","type":"post","link":"https:\/\/system.camp\/java\/java-generics\/","title":{"rendered":"Java Generics"},"content":{"rendered":"\n

Introduction<\/h4>\n\n\n\n

Java generics is a powerful feature introduced in JDK 5.0 that was directed towards improving the quality of code through abstraction<\/em>. It aims to improve code reusability by providing a mechanism to write classes and functions in such a way that types can be passed as parameters.<\/p>\n\n\n\n

Let\u2019s see some code with and without generics. Now, you all must be aware of the list data structure, let us see it in action!<\/p>\n\n\n\n

\/\/ A list of strings without using Generics\nList listWithoutGenerics = new ArrayList();\nlistWithoutGenerics.add(\"Hello\");\nString helloString1 = (String) listWithoutGenerics.get(0);\n\n\/\/ A list of string using Generics\nList<String> listWithGenerics = new ArrayList<String>();\nlistWithGenerics.add(\"Hello\");\nString helloString2 = listWithGenerics.get(0);<\/code><\/pre>\n\n\n\n

Using generics helps us avoid explicit<\/em> type casting in such scenarios. By adding the <><\/code> operator, we helped the compiler narrow down the type of the list, i.e., String<\/code> which can then be enforced by it.<\/p>\n\n\n\n

Generic Methods<\/h4>\n\n\n\n

Generic methods provide great reusability, a single method can be written for which works for arguments of multiple types. Generic methods have some important properties:<\/p>\n\n\n\n

  • They have a diamond <><\/code> operator before the type.<\/li>
  • The diamond operator can contain multiple types separated by commas. (Example – <T, V><\/code>)<\/li><\/ul>\n\n\n\n
    \npublic class Main {\n    public static <T, V> void addNumbers(T t, V v) {\n        System.out.println(t.getClass()); \/\/ prints - class java.lang.Integer\n        System.out.println(v.getClass()); \/\/ prints - class java.lang.String\n    }\n\n    public static void main(String[] args) {\n        addNumbers(5, \"Hello!\");\n    }\n}<\/code><\/pre>\n\n\n\n

    The example below shows how to convert an array of objects to a list of objects:<\/p>\n\n\n\n

    public class Main {\n    public static <T> List<T> fromArrayToList(T[] array) {\n        return Arrays.stream(array).collect(Collectors.toList());\n    }\n\n    public static void main(String[] args) {\n        String[] stringArray = {\"Hello\", \"World\"};\n        Integer[] integerArray = {1, 2, 3, 4, 5};\n        fromArrayToList(stringArray).forEach(System.out::print);\n        System.out.println();\n        fromArrayToList(integerArray).forEach(System.out::print);\n    }\n}<\/code><\/pre>\n\n\n\n

    Bounded Generics<\/h4>\n\n\n\n

    Imagine yourself writing the function to add two numbers. Your first instinct would to be to write a generic method that looks something like this:<\/p>\n\n\n\n

    public static <T> void addTwoNumbers(T a, T b){\n    System.out.println(a + b);\n}<\/code><\/pre>\n\n\n\n

    Sadly, this snippet of code will give you an error. Why, you ask? Simply put, the compiler is not a magician and thus, cannot do something like adding two cars or pigeons!<\/p>\n\n\n\n

    The good news is that we do not need to be magicians to perform an addition of two numbers. We can restrict the type of an object that is passed to the function (a Number in this case). By doing so, we are \u201cbinding\u201d the values of T<\/code> to Number<\/code>.<\/p>\n\n\n\n

    public static <T extends Number> void addTwoNumbers(T a, T b){\n    \/\/ Assume that we need only integer addition for this example\n    System.out.println(a.intValue() + b.intValue());\n}<\/code><\/pre>\n\n\n\n

    Wild cards and Generics<\/h4>\n\n\n\n

    You must be aware that Object<\/code> is the super type of java classes. However, it is very important to note that a collection of Object<\/code> is not a super type for any collection. For example, Object<\/code> is a super type for String<\/code> class but List<Object><\/code> is not a super type for List<String><\/code>.<\/p>\n\n\n\n

    public static void driveVehicles(List<Vehicle> vehicles){\n    vehicles.forEach(Vehicle::drive);\n}<\/code><\/pre>\n\n\n\n

    If you have a function like this, it would not work if you pass a list of cars List<Car><\/code> (assuming Vehicle<\/code> is the super type for Car<\/code>). You can get around this problem using wildcards (?<\/code>). Using the solution below will allow you to use driveVehicles()<\/code> with all subtypes of Vehicle<\/code>.<\/p>\n\n\n\n

    public static void driveVehicles(List<? extends Vehicle> vehicles){\n    vehicles.forEach(Vehicle::drive);\n}<\/code><\/pre>\n\n\n\n

    Type Erasure<\/h4>\n\n\n\n

    Contrary to popular belief, Java Generics are not a runtime feature but a compile-time feature. This essentially means that Java replaces all the type parameters with the bounded object if available, Object<\/code> class otherwise. This concept is called Type Erasure<\/em>.<\/p>\n\n\n\n

    This means that a List<T><\/code> actually becomes List<Object><\/code> after compilation<\/em>. It also explains the reason why you cannot<\/em> pass primitive data types (Ex. Object<\/code> is not a supertype for int<\/code>).<\/p>\n","protected":false},"excerpt":{"rendered":"

    Java generics is a powerful feature introduced in JDK 5.0 that was directed towards improving the quality of code through abstraction. It aims to improve code reusability by providing a mechanism to write classes and functions in such a way that types can be passed as parameters.<\/p>\n","protected":false},"author":2,"featured_media":2438,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_mi_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[40,35],"tags":[10,68,3,69],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/system.camp\/wp-json\/wp\/v2\/posts\/2437"}],"collection":[{"href":"https:\/\/system.camp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/system.camp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/system.camp\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/system.camp\/wp-json\/wp\/v2\/comments?post=2437"}],"version-history":[{"count":5,"href":"https:\/\/system.camp\/wp-json\/wp\/v2\/posts\/2437\/revisions"}],"predecessor-version":[{"id":2444,"href":"https:\/\/system.camp\/wp-json\/wp\/v2\/posts\/2437\/revisions\/2444"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/system.camp\/wp-json\/wp\/v2\/media\/2438"}],"wp:attachment":[{"href":"https:\/\/system.camp\/wp-json\/wp\/v2\/media?parent=2437"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/system.camp\/wp-json\/wp\/v2\/categories?post=2437"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/system.camp\/wp-json\/wp\/v2\/tags?post=2437"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}