{"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
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 Using generics helps us avoid explicit<\/em> type casting in such scenarios. By adding the 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 The example below shows how to convert an array of objects to a list of objects:<\/p>\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 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 You must be aware that If you have a function like this, it would not work if you pass a list of cars 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, This means that a 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}]}}\/\/ 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
<><\/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
<><\/code> operator before the type.<\/li>
<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
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
public static <T> void addTwoNumbers(T a, T b){\n System.out.println(a + b);\n}<\/code><\/pre>\n\n\n\n
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
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
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
Object<\/code> class otherwise. This concept is called Type Erasure<\/em>.<\/p>\n\n\n\n
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":"