The Java Generics programming is introduced in J2SE 5 to deal with type-safe objects. It makes the code stable by detecting the bugs at compile time.

一、Advantages of Generics:

1. Code Reuse

We can write a method/class/interface once and use for any type we want.

2. Type Safety

Generics make errors to appear compile time than at run time (It’s always better to know problems in your code at compile time rather than making your code fail at run time). Suppose you want to create an ArrayList that store name of students and if by mistake programmer adds an integer object instead of string, compiler allows it. But, when we retrieve this data from ArrayList, it causes problems at runtime.

List list = new ArrayList();
list.add(10);
list.add("10");
With Generics, it is required to specify the type of object we need to store.
List<Integer> list = new ArrayList<Integer>();
list.add(10);
list.add("10");// compile-time error
3. Individual Type Casting is not needed

If we do not use generics, then, in the above example every-time we retrieve data from ArrayList, we have to typecast it. Typecasting at every retrieval operation is a big headache. If we already know that our list only holds string data then we need not to typecast it every time.

List list = new ArrayList();
list.add("hello");
String s = (String) list.get(0);//typecasting
After Generics, we don't need to typecast the object.
List<String> list = new ArrayList<String>();
list.add("hello");
String s = list.get(0);
4. Compile-Time Checking

It is checked at compile time so problem will not occur at runtime. The good programming strategy says it is far better to handle the problem at compile time than runtime.

List<String> list = new ArrayList<String>();
list.add("hello");
list.add(32);//Compile Time Error

二、Type Parameters

The type parameters naming conventions are important to learn generics thoroughly. The common type parameters are as follows:

T - Type
E - Element
K - Key
N - Number
V - Value

三、Generic class

A class that can refer to any type is known as a generic class. Here, we are using the T type parameter to create the generic class of specific type.

Let’s see a simple example to create and use the generic class.
Creating a generic class:

class MyGen<T>{
T obj;
void add(T obj){this.obj=obj;}
T get(){return obj;}
}

The T type indicates that it can refer to any type (like String, Integer, and Employee). The type you specify for the class will be used to store and retrieve the data.

Using generic class:

class TestGenerics3{
public static void main(String args[]){
MyGen<Integer> m=new MyGen<Integer>();
m.add(2);
//m.add("vivek");//Compile time error
System.out.println(m.get());
}}

四、Generic Method

Like the generic class, we can create a generic method that can accept any type of arguments. Here, the scope of arguments is limited to the method where it is declared. It allows static as well as non-static methods.

public class TestGenerics4{  public static < E > void printArray(E[] elements) {  for ( E element : elements){          System.out.println(element );  }  System.out.println();  }  public static void main( String args[] ) {  Integer[] intArray = { 10, 20, 30, 40, 50 };  Character[] charArray = { 'J', 'A', 'V', 'A', 'T','P','O','I','N','T' };  System.out.println( "Printing Integer Array" );  printArray( intArray  );   System.out.println( "Printing Character Array" );  printArray( charArray );   }
}

Output:

Printing Integer Array
10
20
30
40
50
Printing Character Array
J
A
V
A
T
P
O
I
N
T

五、Wildcard in Java Generics

The ? (question mark) symbol represents the wildcard element. It means any type. If we write <? extends Number>, it means any child class of Number, e.g., Integer, Float, and double. Now we can call the method of Number class through any child class object.

We can use a wildcard as a type of a parameter, field, return type, or local variable. However, it is not allowed to use a wildcard as a type argument for a generic method invocation, a generic class instance creation, or a supertype.

import java.util.*;
abstract class Shape{
abstract void draw();
}
class Rectangle extends Shape{
void draw(){System.out.println("drawing rectangle");}
}
class Circle extends Shape{
void draw(){System.out.println("drawing circle");}
}
class GenericTest{
//creating a method that accepts only child class of Shape
public static void drawShapes(List<? extends Shape> lists){
for(Shape s:lists){
s.draw();//calling method of Shape class by child class instance
}
}
public static void main(String args[]){
List<Rectangle> list1=new ArrayList<Rectangle>();
list1.add(new Rectangle());  List<Circle> list2=new ArrayList<Circle>();
list2.add(new Circle());
list2.add(new Circle());  drawShapes(list1);
drawShapes(list2);
}}

Output:

drawing rectangle
drawing circle
drawing circle

六、Upper Bounded Wildcards

The purpose of upper bounded wildcards is to decrease the restrictions on a variable. It restricts the unknown type to be a specific type or a subtype of that type. It is used by declaring wildcard character ("?") followed by the extends (in case of, class) or implements (in case of, interface) keyword, followed by its upper bound.
Syntax:

List<? extends Number>

Here,

? is a wildcard character.

extends, is a keyword.

Number, is a class present in java.lang package

Suppose, we want to write the method for the list of Number and its subtypes (like Integer, Double). Using List<? extends Number> is suitable for a list of type Number or any of its subclasses whereas List works with the list of type Number only. So, List<? extends Number> is less restrictive than List.
Example of Upper Bound Wildcard:

import java.util.ArrayList;  public class UpperBoundWildcard {  private static Double add(ArrayList<? extends Number> num) {  double sum=0.0;  for(Number n:num)  {  sum = sum+n.doubleValue();  }  return sum;  }  public static void main(String[] args) {  ArrayList<Integer> l1=new ArrayList<Integer>();  l1.add(10);  l1.add(20);  System.out.println("displaying the sum= "+add(l1));  ArrayList<Double> l2=new ArrayList<Double>();  l2.add(30.0);  l2.add(40.0);  System.out.println("displaying the sum= "+add(l2));  }  }

Output:

displaying the sum= 30.0
displaying the sum= 70.0

七、Unbounded Wildcards

The unbounded wildcard type represents the list of an unknown type such as List<?>. This approach can be useful in the following scenarios: -

When the given method is implemented by using the functionality provided in the Object class.
When the generic class contains the methods that don’t depend on the type parameter.

Example of Unbounded Wildcards

import java.util.Arrays;
import java.util.List;  public class UnboundedWildcard {  public static void display(List<?> list)  {  for(Object o:list)  {  System.out.println(o);  }  }  public static void main(String[] args) {  List<Integer> l1=Arrays.asList(1,2,3);  System.out.println("displaying the Integer values");  display(l1);  List<String> l2=Arrays.asList("One","Two","Three");  System.out.println("displaying the String values");  display(l2);  }  }

Output:

displaying the Integer values
1
2
3
displaying the String values
One
Two
Three

八、Lower Bounded Wildcards

The purpose of lower bounded wildcards is to restrict the unknown type to be a specific type or a supertype of that type. It is used by declaring wildcard character ("?") followed by the super keyword, followed by its lower bound.
Syntax:

List<? super Integer>

Here,

? is a wildcard character.

super, is a keyword.

Integer, is a wrapper class.

Suppose, we want to write the method for the list of Integer and its supertype (like Number, Object). Using List<? super Integer> is suitable for a list of type Integer or any of its superclasses whereas List works with the list of type Integer only. So, List<? super Integer> is less restrictive than List.

Example of Lower Bound Wildcard:

import java.util.Arrays;
import java.util.List;  public class LowerBoundWildcard {  public static void addNumbers(List<? super Integer> list) {  for(Object n:list)  {  System.out.println(n);  }  }
public static void main(String[] args) {  List<Integer> l1=Arrays.asList(1,2,3);  System.out.println("displaying the Integer values");  addNumbers(l1);  List<Number> l2=Arrays.asList(1.0,2.0,3.0);  System.out.println("displaying the Number values");  addNumbers(l2);
}  }

Output:

displaying the Integer values
1
2
3
displaying the Number values
1.0
2.0
3.0

九、What is not allowed to do with Generics?

1.You can’t have static field of type

You can not define a static generic parameterized member in your class. Any attempt to do so will generate compile time error: Cannot make a static reference to the non-static type T.

public class GenericsExample<T>
{private static T member; //This is not allowed
}
2. You can not create an instance of T

Any attempt to create an instance of T will fail with error: Cannot instantiate the type T.

public class GenericsExample<T>
{public GenericsExample(){new T();}
}
3.Generics are not compatible with primitives in declarations

Yes, it’s true. You can’t declare generic expression like List or Map<String, double>. Definitely you can use the wrapper classes in place of primitives and then use primitives when passing the actual values. These value primitives are accepted by using auto-boxing to convert primitives to respective wrapper classes.

final List<int> ids = new ArrayList<>();    //Not allowedfinal List<Integer> ids = new ArrayList<>(); //Allowed
4.You can’t create Generic exception class

Sometimes, programmer might be in need of passing an instance of generic type along with exception being thrown. This is not possible to do in Java.

// causes compiler error
public class GenericException<T> extends Exception {}

When you try to create such an exception, you will end up with message like this: The generic class GenericException may not subclass java.lang.Throwable.

Generics in Java相关推荐

  1. Java Generics示例教程 - 通用方法,类,接口

    Java Generics示例教程 - 通用方法,类,接口 Java Genrics是Java 5中引入的最重要的功能之一.如果您一直在使用Java Collections 对于版本5或更高版本,我确 ...

  2. Java Generics

    一 Generics简介 Generics 是程序设计语言的一种技术,指将程序中数据类型进行参数化,它本质上是对程序的数据类型进行一次抽象,扩展语言的表达能力,同时支持更大粒度的代码复用. 对于一些数 ...

  3. Java - The Basics of Java Generics

    分享一个大牛的人工智能教程.零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击http://www.captainbed.net 1. Introduction Java Gener ...

  4. Java Development - Generics

    Java Development - Generics 1. What 1.1 什么是泛型 (What is Generics) 1.2 泛型的作用 (Need for Generics) 2. Wh ...

  5. Java ConcurrentHashMap Example and Iterator--转

    原文地址:http://www.journaldev.com/122/java-concurrenthashmap-example-iterator#comment-27448 Today we wi ...

  6. Java泛型的类型擦除

    写在前面:最近在看泛型,研究泛型的过程中,发现了一个比较令我意外的情况,Java中的泛型基本上都是在编译器这个层次来实现的.在生成的Java字节代码中是不包含泛型中的类型信息的.使用泛型的时候加上的类 ...

  7. Java深度历险(五)——Java泛型

    Java泛型(generics)是JDK 5中引入的一个新特性,允许在定义类和接口的时候使用类型参数(type parameter).声明的类型参数在使用时用具体的类型来替换.泛型最主要的应用是在JD ...

  8. Java泛型学习资料小汇

    <Effective Java>的第二版,第5章 泛型 ★★★★★ 2008年5月出的<Effective Java>的第二版涵盖了Java SE 5和Java SE 6. 其 ...

  9. [CareerCup] 14.4 Templates Java模板

    14.4 Explain the difference between templates in C++ and generics in Java. 在Java中,泛式编程Generic Progra ...

最新文章

  1. java金额小写转大写(8.2)
  2. Windows 10 系统版本更新历史
  3. 信息系统项目管理知识--项目配置管理
  4. getContextPath、getServletPath、getRequestURI的区别
  5. linux之awk命令学习笔记
  6. CentOS7 安装MongoDB 3.0服务
  7. ubuntu 下操作目录,出现Permission denied的解决办法
  8. 程序员必须尽早作打算
  9. 去掉chrome、safari input或textarea在得到焦点时出现黄色边框的方法
  10. bytearrayinputstream java_java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)...
  11. 收拾了一下书架,感觉还是像破烂货市场一样
  12. 惠普打印机换硒鼓图解_hp硒鼓怎么安装 hp硒鼓安装方法这图文教程】
  13. MOV 和MOVS 这两条指令有什么区别?
  14. 【活动报名】NEO 区块链公开课(1): NEO 区块链开发入门
  15. vivo Y51的USB调试模式在哪里,开启vivo Y51USB调试模式的教程
  16. 企业邮箱是什么?企业邮箱有什么好处?企业邮箱域名怎么设置?
  17. ShareREC for iOS录屏原理解析
  18. 自学Python:快速查找文件或文件夹
  19. Gitee配置静态页面
  20. 【论文笔记】AVSM:结合了仿射配准和vSVF配准的医学图像配准模型

热门文章

  1. 如何清理GPU的使用
  2. 中国医科大学22春《妇产科护理学(本科)》在线作业【标准答案】
  3. 计算机科学系毕业条幅,大学毕业典礼横幅标语
  4. 真4K还是假4K游戏 解构PS4pro棋盘渲染技术
  5. (白帽子学习笔记)前渗透——SQL注入
  6. android OTA系统升级流程
  7. srpingboot+vue整合websocket实现在线群聊系统
  8. 卡尔曼滤波以后再经过低通滤波器_卡尔曼滤波:究竟滤了谁?
  9. 解读:百度将处理不相关静态搜索结果页
  10. 新东方 2017 财年:将新增 40-50 家 K12 学习中心,继续试点双师课堂