1.TestMakePair2.java
package javacore.chapter8;
import java.util.function.Supplier;
public class TestMakePair2 {
public static void main(String[] args) {
// 1.接受Suppier<T>--它是一个函数式接口。表示无参数且返回类型为T的函数。
/**
* 因为不能实例化类型变量,如:
* public Pair2 {first = new T();second = new T();}
* 所以最好的方式是让调用者提供一个构造器表达式.形式如下:
* @param constr
* @return
*/
Pair2<String> pair2 = Pair2.makePair(String::new);
System.out.println(pair2.getFirst().length());
/**
* public void makeT(){
2.传统的方式是通过Class.newInstance方法来构造泛型对象.
但由于细节过于复杂,T.class是不合法的.它会被擦除为Object.class.如下:
Illegal class literal for the type parameter T
T.class.newInstance();
}
* 3.
* T.class是不合法的,但若API設計為如下形式卻可以
* reason:因為String.class是Class<String>的一個实例.
*/
Pair2<String> pair = Pair2.makePair(String.class);
}
}
class Pair2<T> {
private T first;
private T second;
public T getFirst() {
return first;
}
public void setFirst(T first) {
this.first = first;
}
public T getSecond() {
return second;
}
public void setSecond(T second) {
this.second = second;
}
public Pair2(T first, T second) {
this.first = first;
this.second = second;
}
public static <T> Pair2<T> makePair(Supplier<T> constr) {
return new Pair2<>(constr.get(), constr.get());
}
/**
* Cannot infer type arguments for Pair2<>
* 当函数头返回值为Pair时,无法推断,改为Pair2后可以推断.
* @param c1
* @return
*/
public static <T> Pair2<T> makePair(Class<T> c1){
try {
return new Pair2<>(c1.newInstance(),c1.newInstance());
} catch (InstantiationException | IllegalAccessException e) {
return null;
}
}
}