三.泛型方法
泛型并不是一定要应用于整个类的,我们也可以给类中的方法加上参数化类型。其实,是否拥有泛型方法,与其所在类是否是泛型并没有必然的关系。换句话说,我们可以个一个不是泛型的类加上泛型方法,也可以在具有泛型的类中加入非泛型的方法。
下面是泛型方法的简单例子:
注意,如果我们调用f()时传入的是基本类型,java的自动打包机制会介入其中。譬如上面代码的 gm.f(1)输出的结果将会是java.lang.Integer。
也许大家也注意到上面代码我们调用f()的时候并没有像泛型类那这样需要给他赋予具体的的参数类型,因为对于泛型方法,java编译器提供了类型推断的机制。我们只要把具体的参数传递进去方法,编译器会自动地对参数类型进行推断。
但是,有一点需要注意的,类型推断只对赋值操作有效。请看下面代码:
为了解决上面的问题,我们可以显式地指明类型。例子如下:
现在我们已经解决了参数类型推断只对赋值操作有效的问题。但是这种语法也抵销了泛型方法带来的方便。
四.泛型匿名内部类
由于比较简单,直接看例子就可以了:
泛型并不是一定要应用于整个类的,我们也可以给类中的方法加上参数化类型。其实,是否拥有泛型方法,与其所在类是否是泛型并没有必然的关系。换句话说,我们可以个一个不是泛型的类加上泛型方法,也可以在具有泛型的类中加入非泛型的方法。
下面是泛型方法的简单例子:
public
class
GenericMethod
{
public <T> void f(T x)
{
System.out.println(x.getClass().getName());
}
public static void main(String[] args)
{
GenericMethod gm = new GenericMethod();
gm.f("1");
gm.f(1);
gm.f(gm);
}
}
public <T> void f(T x)
{
System.out.println(x.getClass().getName());
}
public static void main(String[] args)
{
GenericMethod gm = new GenericMethod();
gm.f("1");
gm.f(1);
gm.f(gm);
}
}
注意,如果我们调用f()时传入的是基本类型,java的自动打包机制会介入其中。譬如上面代码的 gm.f(1)输出的结果将会是java.lang.Integer。
也许大家也注意到上面代码我们调用f()的时候并没有像泛型类那这样需要给他赋予具体的的参数类型,因为对于泛型方法,java编译器提供了类型推断的机制。我们只要把具体的参数传递进去方法,编译器会自动地对参数类型进行推断。
但是,有一点需要注意的,类型推断只对赋值操作有效。请看下面代码:
import
java.util.ArrayList;
public class GenericMethod {
public <T> ArrayList<T> array()
{
return new ArrayList<T>();
}
public static void f(ArrayList<String> a)
{
}
public static void main(String[] args)
{
GenericMethod gm = new GenericMethod();
// OK
ArrayList<String> ay = gm.array();
// Compile Error
f(gm.array());
}
}
public class GenericMethod {
public <T> ArrayList<T> array()
{
return new ArrayList<T>();
}
public static void f(ArrayList<String> a)
{
}
public static void main(String[] args)
{
GenericMethod gm = new GenericMethod();
// OK
ArrayList<String> ay = gm.array();
// Compile Error
f(gm.array());
}
}
为了解决上面的问题,我们可以显式地指明类型。例子如下:
import
java.util.ArrayList;
public class GenericMethod {
public <T> ArrayList<T> array()
{
return new ArrayList<T>();
}
public static void f(ArrayList<String> a)
{
}
public static void main(String[] args)
{
GenericMethod gm = new GenericMethod();
// OK
ArrayList<String> ay = gm.array();
// Now Ok
f(gm.<String> array());
}
}
public class GenericMethod {
public <T> ArrayList<T> array()
{
return new ArrayList<T>();
}
public static void f(ArrayList<String> a)
{
}
public static void main(String[] args)
{
GenericMethod gm = new GenericMethod();
// OK
ArrayList<String> ay = gm.array();
// Now Ok
f(gm.<String> array());
}
}
现在我们已经解决了参数类型推断只对赋值操作有效的问题。但是这种语法也抵销了泛型方法带来的方便。
四.泛型匿名内部类
由于比较简单,直接看例子就可以了:
public
interface
GenericInterface
<
T
>
{
T next();
}
public class GenericInnerClass1 {
private static long counter = 1;
private final long id = counter++;
private GenericInnerClass1()
{
}
public static GenericInterface<GenericInnerClass1> generator()
{
return new GenericInterface<GenericInnerClass1> ()
{
public GenericInnerClass1 next()
{
return new GenericInnerClass1();
}
};
}
public long getId() {
return id;
}
}
public class GenericInnerClass2 {
private static long counter = 1;
private final long id = counter++;
private GenericInnerClass2()
{
}
public static GenericInterface<GenericInnerClass2> generator()
{
return new GenericInterface<GenericInnerClass2> ()
{
public GenericInnerClass2 next()
{
return new GenericInnerClass2();
}
};
}
public long getId() {
return id;
}
}
public class GenericInnerClassTest {
public static void main(String[] args) {
GenericInnerClass1 gic1 = GenericInnerClass1.generator().next();
System.out.println(gic1.getId());
GenericInnerClass2 gic2 = GenericInnerClass2.generator().next();
System.out.println(gic2.getId());
}
}
T next();
}
public class GenericInnerClass1 {
private static long counter = 1;
private final long id = counter++;
private GenericInnerClass1()
{
}
public static GenericInterface<GenericInnerClass1> generator()
{
return new GenericInterface<GenericInnerClass1> ()
{
public GenericInnerClass1 next()
{
return new GenericInnerClass1();
}
};
}
public long getId() {
return id;
}
}
public class GenericInnerClass2 {
private static long counter = 1;
private final long id = counter++;
private GenericInnerClass2()
{
}
public static GenericInterface<GenericInnerClass2> generator()
{
return new GenericInterface<GenericInnerClass2> ()
{
public GenericInnerClass2 next()
{
return new GenericInnerClass2();
}
};
}
public long getId() {
return id;
}
}
public class GenericInnerClassTest {
public static void main(String[] args) {
GenericInnerClass1 gic1 = GenericInnerClass1.generator().next();
System.out.println(gic1.getId());
GenericInnerClass2 gic2 = GenericInnerClass2.generator().next();
System.out.println(gic2.getId());
}
}