原文
Generics in Java. It’s all about type safety | by Salitha Chathuranga | Medium
引言
It’s all about type safety。
所有内容都是关于线程安全。
Hi all!!!
I thought of writing a widely used but less discussed topic in Java. That is Generics! We use it, but majority of the developers don’t know about it as I have experienced.
本次编写的有关内容是讨论较少主题,“泛型”,实际上我们经常使用(实际上天天都在用),但是大部分人并不了解。
Let me clear this…have you ever used List or ArrayList in Java? Most probably, answer should be YES. Right? Without collections, we can’t even think of an easy way of handling data. So, do you remember how we define an ArrayList?
让我澄清一下......您在Java中使用过List或ArrayList吗?答案很可能是 "是"。对不对?如果没有集合,我们甚至无法想象处理数据的简单方法。那么,你还记得我们是如何定义ArrayList的吗?
List<Integer> numbers = new ArrayList<>(); // with Generics
This is the way we declare it. So, we have used generics. 😃 Here, _
_ is the Generic we passed. That is a Type. After we create list like this, you can only add integers to the list.
在上面的例子中我们在泛型中指定,之后我们创建的List只能添加整型类型数据。
You may remember, if we define the list like below, we would be able to add any type of data which is extended from Object super class, to the list.
如果我们在定义List的时候不指定任何泛型,我们可以添加任意类型的数据,这些数据是从对象超类中扩展出来的。
List numbers = new ArrayList(); // without Generics
We can achieve Type Safety for this List, after we add generics.
为了实现类型安全,之后我们可以添加泛型。
Generics means parameterized types. Java let us to create a single class, interface, and method that can be used with different types of data(objects) within the Generics domain.
泛型也叫参数化类型,Java允许我们创建单一的类、接口和方法,这些类、接口和方法可用于泛型域内的不同类型的数据(对象)。
Advantages in Generics would be:
泛型的优点如下:
- Code Reusability — we can use a common code with multiple object types
代码复用性:我们可以使用通用代码包含多种不同对象类型。
- Compile-time Type Checking — Java will check the generics code at the compile time against errors
编译时期的类型检查:实现Java在编译时期进行类型检查。
- Type Safety — we can restrict adding unnecessary data
类型安全:可以限制添加不必要的数据
- Usage in Collections — Collections need object types to deal with data
集合中使用:集合需要对象类型的数据,泛型可以更好的控制。
Let’s take and example to explain why we need Generics..
下面举个栗子介绍为什么需要泛型。
Imagine you have to print Numbers and Texts using a printer class. Printer has a method that accepts the data while creating it.
想象一下你需要数字或者文本类型的打印机对象,打印机在创建时有一个接受数据的方法。
In traditional way, we will have to creat 2 classes since we have 2 types of data: Number(Integer) and Text(String).
按照传统的方式,我们会创建两个对象,根据需要的打印机类型构建字符串和整型(打印机)对象。
public class TextPrinter { private final String data; public TextPrinter(String data) { this.data = data; } public void print() { System.out.println("print::: " + data); } }
public class NumberPrinter { private final Integer data; public NumberPrinter(Integer data) { this.data = data; } public void print() { System.out.println("print::: " + data); } }
How to use:
public class GenericsMain { public static void main(String[] args) { NumberPrinter numberPrinter = new NumberPrinter(5); numberPrinter.print(); // output = print::: 5 TextPrinter textPrinter = new TextPrinter("Hello"); textPrinter.print(); // output = print::: Hello } }
You can see we have code duplication! Data type is the only difference here!
你会发现这里有重复代码,这里仅仅是对象类型不同。
We can simply use a Printer with a Generic here. Then we will only have 1 Printer! 😎
只需要非常简单的添加一个泛型,
Let’s deep dive into Generics and see how we achieve this… 😎
让我们深入了解泛型,看看如何实现这一点......
Create a Generic 创建通用型
I’m taking the above simple example and will show how to create a Generic Printer.
我将以上面的简单示例来说明如何创建一个通用打印机。
public class Printer<T> { private final T data; public Printer(T data) { this.data = data; } public void print() { System.out.println("print::: " + data); } }
How to use:
Printer<Integer> integerPrinter = new Printer<>(5); integerPrinter.print(); // output = print::: 5 Printer<String> stringPrinter = new Printer<>("Hello"); stringPrinter.print(); // output = print::: Hello Printer<Double> doublePrinter = new Printer<>(45.34); doublePrinter.print(); // output = print::: 45.34 Printer<Long> longPrinter = new Printer<>(5L); longPrinter.print();z // output = print::: 5
Now we only have 1 class! It accepts a Type. Here, T is used to denote the Type as a common standard. We can even create printer objects for other data types also like Double/Long. Code reusability is achieved in style. 😎
现在我们只需要一个类就可以完成构建两种不同类型的打印机,这里的 T 表示作为通用标准的类型,我们甚至可以把这个T改为 Double/Long 类型,最终实现了 “代码重用性” 的风格。
We can create Generic classes which accepts more than 1 type. Look at the below example. It accepts an Integer and a String both.
我们可以创建接受多种类型的通用类。请看下面的示例,它同时接受一个整数和一个字符串。
public class MultiPrinter<T, V> { private final T data1; private final V data2; public MultiPrinter(T data1, V data2) { this.data1 = data1; this.data2 = data2; } public void print() { System.out.println("print::: " + data1 + " : " + data2); } }
MultiPrinter<Integer, String> multiPrinter = new MultiPrinter<>(5, "Hello"); multiPrinter.print(); // output = print::: 5 : Hello
Java Type Naming conventions
- E — Element (used in Collections)
- K — Key (Used in Map)
- N — Number
- T — Type
- V — Value (Used in Map)
- S, U, V etc. — 2nd, 3rd, 4th types
Java类型命名规则
- E - 元素(在集合中使用)
- K - 键(在地图中使用)
- N - 数字
- T - 类型
- V - 值(在映射中使用)
- S、U、V 等 - 第二、第三、第四类型
【Java】Generics in Java(二)https://developer.aliyun.com/article/1395319