Java泛型方法和构造函数是Java中的两种不同的类型,它们都可以用来创建可重用的代码。但是,它们之间也存在一些明显的差异。
首先,Java泛型方法是一种特殊的方法,它可以被声明为接受一个或多个类型参数。这些参数可以用来控制方法的行为,并使得该方法能够被多次重用。而Java构造函数则是一种特殊的函数,它用于初始化对象并将其放入内存中。
其次,Java泛型方法必须声明为静态方法才能使用,而Java构造函数不需要声明为静态函数就能使用。此外,Java泛型方法还必须有返回类型(即使是void也行),而Java构造函数不需要有返回类型。
最后,Java泛型方法必须在被调用时传入相应的参数才能正常工作,而Java构造函数则不需要传入任何参数就能正常工作。
public class GenericMethodExample { public staticvoid printArray(T[] array) { for (T element : array) { System.out.println(element); } } public static void main(String[] args) { Integer[] intArray = {1, 2, 3, 4, 5}; Double[] doubleArray = {1.1, 2.2, 3.3, 4.4}; Character[] charArray = {'H', 'E', 'L', 'L', 'O'}; System.out.println("Integer Array:"); printArray(intArray); // 传递一个 Integer 泛型数组 System.out.println("Double Array:"); printArray(doubleArray); // 传递一个 Double 泛型数组 System.out.println("Character Array:"); printArray(charArray); // 传递一个 Character 泛型数组 } }
我们可以在方法声明中定义类型参数,它们在方法的返回类型之前的尖括号中指定。
包含泛型方法声明的类型不必是泛型类型。
我们可以在非静态方法声明中使用为泛型类型指定的类型参数。
以下代码显示如何为方法m1()定义新的类型参数V.
新类型参数V强制方法m1()的第一个和第二个参数为相同类型。
第三个参数必须是相同的类型T,这是类实例化的类型。
class MyBag<T> { private T ref; public MyBag(T ref) { this.ref = ref; } public T get() { return ref; } public void set(T a) { this.ref = a; } } class Test<T> { public <V> void m1(MyBag<V> a, MyBag<V> b, T c) { } }
要传递方法的形式类型参数的实际类型参数,我们必须在方法调用中的点和方法名之间的尖括号<>中指定它。
class MyBag<T> { private T ref; public MyBag(T ref) { this.ref = ref; } public T get() { return ref; } public void set(T a) { this.ref = a; } } class Test<T> { public <V> void m1(MyBag<V> a, MyBag<V> b, T c) { } } public class Main { public static void main(String[] argv) { Test<String> t = new Test<String>(); MyBag<Integer> iw1 = new MyBag<Integer>(new Integer(201)); MyBag<Integer> iw2 = new MyBag<Integer>(new Integer(202)); // Specify that Integer is the actual type for the type parameter for m1() t.<Integer>m1(iw1, iw2, "hello"); t.m1(iw1, iw2, "hello"); } }
以下代码显示了如何声明泛型静态方法。
我们不能在静态方法内引用包含类的类型参数。
静态方法只能引用它自己声明的类型参数。
以下静态通用类型定义了类型参数T,用于约束参数source和dest的类型。
class MyBag<T> { private T ref; public MyBag(T ref) { this.ref = ref; } public T get() { return ref; } public void set(T a) { this.ref = a; } } public class Main { public static <T> void copy(MyBag<T> source, MyBag<? super T> dest) { T value = source.get(); dest.set(value); } public static void main(String[] argv) { } }
要为静态方法调用指定实际的类型参数,我们可以这样做:
Main.<Integer>copy(iw1, iw2);
我们可以为构造函数定义类型参数。
下面的代码定义了类Test的构造函数的类型参数U.
它放置一个约束,即构造函数的类型参数U必须是相同的,或者它的类类型参数T的实际类型的子类型。
public class Test<T> { public <U extends T> Test(U k) { } }
要为构造函数指定实际的类型参数值,请在新运算符和构造函数名称之间的尖括号中指定它,如以下代码段所示:
class Test<T> { public <U extends T> Test(U k) { } } public class Main { public static void main(String[] argv) { // Specify the actual type parameter for the constructor as Double Test<Number> t1 = new<Double> Test<Number>(new Double(1.9)); // Let the compiler figure out, Integer is // the actual type parameter for the constructor Test<Number> t2 = new Test<Number>(new Integer(1)); } }
Java 7在泛型类型的对象创建表达式中增加了对类型推断的有限支持。
对于以下语句:
List<String> list = new ArrayList<String>();
在Java 7中,可以在上面的语句中指定空尖括号,称为菱形操作符或简单的菱形<>作为ArrayList的类型参数。
List<String> list = new ArrayList<>();
如果我们不在对象创建表达式中为泛型类型指定类型参数,那么类型是原始类型,编译器生成未检查的警告。
例如,以下语句将编译未选中的警告:
List<String> list = new ArrayList(); // Generates an unchecked warning
我们不能创建泛型的异常类。并且没有泛型的匿名类。
Java面向对象设计 -Java注释用法注释元素的提供值必须是编译时常量表达式,我们不能使用null作为注释中任何类型元素的值。原始类...
Java面向对象设计 - Java枚举类型什么是枚举类型?枚举类型创建常量的有序列表作为类型。它以特定顺序指定常量。在枚举类型中定...
Java面向对象设计 -Java枚举主体将主体添加到枚举常量我们可以为每个枚举常量添加一个不同的体。身体可以有字段和方法。枚举常量...
Java面向对象设计 -Java接口方法方法声明您可以在接口中声明三种类型的方法:抽象方法静态方法默认方法在Java 8之前,您只能在接...