Java泛型通配符是Java泛型的一种特殊形式,它可以用来表示任何类型。它的语法是在一个类型参数前面加上问号(?)。它可以用来指定一个未知的类型,而不必指定具体的类型。
Java泛型通配符有三种形式:>, extends X> 和 super X>。>表示任意的Java泛型对象, extends X>表示X或X的子类,而 super X>表示X或X的超类。
Java泛型通配符可以用来声明方法参数、返回值、字段、本地变量或者异常处理语句中使用。例如:
public static void printList(List extends Number> list) {
for (Number n : list) {
System.out.println(n);
}
}
上面这个方法声明了一个List<? extends Number>作为参数,这意味着该方法接受所有Number子类作为参数。
此外,Java泛型通配符也可以用于创建对象实例。例如:
Class<?> clazz = Class.forName("java.lang.String");
Object obj = clazz.newInstance(); // 创建String对象实例
泛型(Generic) 允许您延迟编写类或方法中的编程元素的数据类型的规范,直到实际在程序中使用它的时候。换句话说,泛型允许您编写一个可以与任何数据类型一起工作的类或方法。
您可以通过数据类型的替代参数编写类或方法的规范。当编译器遇到类的构造函数或方法的函数调用时,它会生成代码来处理指定的数据类型。下面这个简单的实例将有助于您理解这个概念:
using System;
using System.Collections.Generic;
namespace GenericApplication{
public class MyGenericArray<T>{
private T[] array;
public MyGenericArray(int size){
array = new T[size + 1];
}
public T getItem(int index){
return array[index];
}
public void setItem(int index, T value){
array[index] = value;
}
}
class Tester{
static void Main(string[] args){
// 声明一个整型数组
MyGenericArray<int> intArray = new MyGenericArray<int>(5);
// 设置值
for (int c = 0; c < 5; c++){
intArray.setItem(c, c * 5);
} // 获取值
for (int c = 0; c < 5; c++){
Console.Write(intArray.getItem(c) + " ");
}
Console.WriteLine(); // 声明一个字符数组
MyGenericArray<char> charArray = new MyGenericArray<char>(5);
// 设置值
for (int c = 0; c < 5; c++){
charArray.setItem(c, (char)(c + 97));
} // 获取值
for (int c = 0; c < 5; c++){
Console.Write(charArray.getItem(c) + " ");
}
Console.WriteLine();
Console.ReadKey();
}
}
}
当上面的代码被编译和执行时,它会产生下列结果:
0 5 10 15 20
a b c d e
使用泛型是一种增强程序功能的技术,具体表现在以下几个方面:
在上面的实例中,我们已经使用了泛型类,我们可以通过类型参数声明泛型方法。下面的程序说明了这个概念:
using System;
using System.Collections.Generic;
namespace GenericMethodAppl{
class Program{
static void Swap<T>(ref T lhs, ref T rhs){
T temp;
temp = lhs;
lhs = rhs;
rhs = temp;
}
static void Main(string[] args){
int a, b;
char c, d;
a = 10;
b = 20;
c = "I";
d = "V";
// 在交换之前显示值
Console.WriteLine("Int values before calling swap:");
Console.WriteLine("a = {0}, b = {1}", a, b);
Console.WriteLine("Char values before calling swap:");
Console.WriteLine("c = {0}, d = {1}", c, d);
// 调用 swap
Swap<int>(ref a, ref b);
Swap<char>(ref c, ref d);
// 在交换之后显示值
Console.WriteLine("Int values after calling swap:");
Console.WriteLine("a = {0}, b = {1}", a, b);
Console.WriteLine("Char values after calling swap:");
Console.WriteLine("c = {0}, d = {1}", c, d);
Console.ReadKey();
}
}
}
当上面的代码被编译和执行时,它会产生下列结果:
Int values before calling swap:
a = 10, b = 20
Char values before calling swap:
c = I, d = V
Int values after calling swap:
a = 20, b = 10
Char values after calling swap:
c = V, d = I
您可以通过类型参数定义泛型委托。例如:
delegate T NumberChanger<T>(T n);
下面的实例演示了委托的使用:
using System;
using System.Collections.Generic;
delegate T NumberChanger<T>(T n);
namespace GenericDelegateAppl{
class TestDelegate{
static int num = 10;
public static int AddNum(int p){
num += p;
return num;
}
public static int MultNum(int q){
num *= q;
return num;
}
public static int getNum(){
return num;
}
static void Main(string[] args){
// 创建委托实例
NumberChanger<int> nc1 = new NumberChanger<int>(AddNum);
NumberChanger<int> nc2 = new NumberChanger<int>(MultNum);
// 使用委托对象调用方法
nc1(25);
Console.WriteLine("Value of Num: {0}", getNum());
nc2(5);
Console.WriteLine("Value of Num: {0}", getNum());
Console.ReadKey();
}
}
}
当上面的代码被编译和执行时,它会产生下列结果:
Value of Num: 35
Value of Num: 175
集合(Collection)类是专门用于数据存储和检索的类。这些类提供了对栈(stack)、队列(queue)、列表(list)和哈希表(hash t...
C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。引用可在...
属性(Property) 是类(class)、结构(structure)和接口(interface)的命名(named)成员。类或结构中的成员变量或方法称为 ...
枚举是一组命名整型常量。枚举类型是使用 enum 关键字声明的。C# 枚举是值数据类型。换句话说,枚举包含自己的值,且不能继承或...
当您定义一个类时,您定义了一个数据类型的蓝图。这实际上并没有定义任何的数据,但它定义了类的名称意味着什么,也就是说,类的...