mirror of
https://github.com/Jueee/effective-Java.git
synced 2025-03-14 03:10:42 +08:00
优先考虑泛型
This commit is contained in:
parent
714400aaf0
commit
a17ea15649
15
ch05泛型/29.优先考虑泛型.md
Normal file
15
ch05泛型/29.优先考虑泛型.md
Normal file
@ -0,0 +1,15 @@
|
||||
## 优先考虑泛型
|
||||
|
||||
|
||||
|
||||
- [Item29Example01.java](Generics/src/main/java/com/jueee/item29/Item29Example01.java):简单堆栈实现。
|
||||
|
||||
- [Item29Example02.java](Generics/src/main/java/com/jueee/item29/Item29Example02.java):泛型化的堆栈实现。
|
||||
|
||||
泛型化类的第一步是在其声明中添加一个或多个类型参数。 在这种情况下,有一个类型参数,表示堆栈的元素类型,这个类型参数的常规名称是 E 。
|
||||
|
||||
消除 `Stack` 中的泛型数组创建错误的第二种方法是将属性元素的类型从 `E[]` 更改为 `Object[]`。
|
||||
|
||||
绝大多数泛型类型就像我们的 `Stack` 示例一样,它们的类型参数没有限制:可以创建一个 `Stack<Object>,Stack<int[]>`,`Stack<List<String>>` 或者其他任何对象的 `Stack` 引用类型。 请注意,不能创建基本类型的堆栈:尝试创建 `Stack<int>` 或 `Stack<double>` 将导致编译时错误。 这是 Java 泛型类型系统的一个基本限制。 可以使用基本类型的包装类(详见第 61 条)来解决这个限制。
|
||||
|
||||
总之,泛型类型比需要在客户端代码中强制转换的类型更安全,更易于使用。 当你设计新的类型时,确保它们可以在没有这种强制转换的情况下使用。 这通常意味着使类型泛型化。 如果你有任何现有的类型,应该是泛型的但实际上却不是,那么把它们泛型化。 这使这些类型的新用户的使用更容易,而不会破坏现有的客户端(条目 26)。
|
@ -0,0 +1,51 @@
|
||||
package com.jueee.item29;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.EmptyStackException;
|
||||
|
||||
public class Item29Example01 {
|
||||
|
||||
// Object-based collection - a prime candidate for generics
|
||||
public class Stack {
|
||||
private Object[] elements;
|
||||
private int size = 0;
|
||||
private static final int DEFAULT_INITIAL_CAPACITY = 16;
|
||||
|
||||
public Stack() {
|
||||
elements = new Object[DEFAULT_INITIAL_CAPACITY];
|
||||
}
|
||||
|
||||
public void push(Object e) {
|
||||
ensureCapacity();
|
||||
elements[size++] = e;
|
||||
}
|
||||
|
||||
public Object pop() {
|
||||
if (size == 0)
|
||||
throw new EmptyStackException();
|
||||
Object result = elements[--size];
|
||||
elements[size] = null; // Eliminate obsolete reference
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return size == 0;
|
||||
}
|
||||
|
||||
private void ensureCapacity() {
|
||||
if (elements.length == size)
|
||||
elements = Arrays.copyOf(elements, 2 * size + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Item29Example01 test = new Item29Example01();
|
||||
Stack stack = test.new Stack();
|
||||
String[] strings = new String[] {"a", "b", "c"};
|
||||
for (String arg : strings)
|
||||
stack.push(arg);
|
||||
while (!stack.isEmpty())
|
||||
System.out.println(stack.pop().toString().toUpperCase());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package com.jueee.item29;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.EmptyStackException;
|
||||
|
||||
public class Item29Example02 {
|
||||
|
||||
// Initial attempt to generify Stack - won't compile!
|
||||
public class Stack<E> {
|
||||
private E[] elements;
|
||||
private int size = 0;
|
||||
private static final int DEFAULT_INITIAL_CAPACITY = 16;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Stack() {
|
||||
elements = (E[])new Object[DEFAULT_INITIAL_CAPACITY];
|
||||
}
|
||||
|
||||
public void push(E e) {
|
||||
ensureCapacity();
|
||||
elements[size++] = e;
|
||||
}
|
||||
|
||||
public E pop() {
|
||||
if (size == 0)
|
||||
throw new EmptyStackException();
|
||||
E result = elements[--size];
|
||||
elements[size] = null; // Eliminate obsolete reference
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return size == 0;
|
||||
}
|
||||
|
||||
private void ensureCapacity() {
|
||||
if (elements.length == size)
|
||||
elements = Arrays.copyOf(elements, 2 * size + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Item29Example02 test = new Item29Example02();
|
||||
Stack<String> stack = test.new Stack<>();
|
||||
String[] strings = new String[] {"a", "b", "c"};
|
||||
for (String arg : strings)
|
||||
stack.push(arg);
|
||||
while (!stack.isEmpty())
|
||||
System.out.println(stack.pop().toUpperCase());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user