JAVA中的泛型用法一种: <T> 返回值用法。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA中的泛型用法一种: <T> 返回值用法。相关的知识,希望对你有一定的参考价值。

public class ExchangeValue
static <T> void f1 (List<T> list) T t = list.get(0) ;
帮忙解释一下<T>的用法?应该不是返回值类型吧,因为写着void呢,呵呵。

1、对于泛型方法来说,是可以接收不同类型的参数,比如下图,使用泛型来操作List集合,然后向List中添加一条数据,看是否可以添加成功,创建泛型方法如图所示。

2、然后在写一个main方法来测试一下这个泛型方法,先向集合中添加一条String类型的数据,打印List集合中的元素,如图所示。

3、上面是往List集合中添加了一个String类型的数据,下图往List集合中添加一条Integer类型的数据并打印,当然也可以自己创建对象进行添加。

4、泛型也是可以限制要使用的参数类型的,比如上面,list集合中,只想加入数字类型的数据,当然也是可以的,只要让类中的T继承Number就行了,如图所示。

5、下面在测试一下,向集合中添加一个Long类型的数据并打印,如图所示。

6、最后输出就完成了。

参考技术A 这个T就是你存入List中的类型 比如说 List<String> 那么你的List中放的就String类型 参考技术B 泛型方法:
  是否拥有泛型方法,与其所在的类是否泛型没有关系。要定义泛型方法,只需将泛型参数列表置于返回值前。如:
public class ExampleA
 public <T> void f(T x)
  System.out.println(x.getClass().getName());
 
 public static void main(String[] args)
  ExampleA ea = new ExampleA();
  ea.f(" ");
  ea.f(10);
  ea.f('a');
  ea.f(ea);
 

输出结果:
java.lang.String
java.lang.Integer
java.lang.Character
ExampleA
  使用泛型方法时,不必指明参数类型,编译器会自己找出具体的类型。泛型方法除了定义不同,调用就像普通方法一样。
  需要注意,一个static方法,无法访问泛型类的类型参数,所以,若要static方法需要使用泛型能力,必须使其成为泛型方法。本回答被提问者采纳

java中的泛型

本文将详细介绍java泛型的用法以及泛型的原理

 

java泛型

泛型是在J2 SE1.5中引入的一个特性 可以将类型抽象为一个参数 从而简化代码和实现类型安全

 

如何使用泛型

泛型可以用于方法 类和接口 通过尖括号加标识符的方式声明

class GenericityClass<T>
{
    T t;
    public GenericityClass(T t)
    {
        this.t = t;
    }
    public T getT()
    {
        return t;
    }
}

interface GenericityInterface<T>
{
    void printGenericity(T t);
}

public static <A> A test(A a)
{
    System.out.println(a);
    return a;
}

其中类型T是一个不确定的类型 需要填入实际类型才能使用

ps1: 可以给泛型参数起任意名称 例如 <T2333> <abcd> <FAN_XING>
ps2: 可以声明任意个泛型参数 不同的泛型参数用‘,‘隔开 例如 <T, E, TD250>

 

使用泛型类,方法与普通的类,方法并没有太大区别 除了要填入尖括号和类型

GenericityClass<String> gc = new GenericityClass<String>("泛型类测试");
String s = gc.getT();
Main.<String>test("泛型方法测试");

因为编译器推导的存在 我们可以省略一些重复的类型信息

GenericityClass<String> gc = new GenericityClass<>("泛型类测试");// 前边的<String>已经声明了类型 后边的就可以省略
String s = gc.getT();
Main.test("泛型方法测试");// 后边填入的参数String已经确定了泛型参数的类型 因此可以省略<String>

 

java泛型的实现原理

java的泛型实现机制并不是类似c++编译时模板生成 也不是c#运行时生成泛型类 而是利用了一套泛型擦除机制

通过观察编译后的字节码 我们发现 编译器将所有的泛型参数都处理成Object类型

class GenericityClass
{
    Object t;
    public GenericityClass(Object t)
    {
        this.t = t;
    }
    public Object getT()
    {
        return t;
    }
}

interface GenericityInterface
{
    void printGenericity(Object t);
}

public static Object test(Object a)
{
    System.out.println(a);
    return a;
}
GenericityClass gc = new GenericityClass("泛型类测试");
String s = (String) gc.getT();// 因为返回值是Object所以要强制转换
BlueBridge.test("泛型方法测试");

 

我们可以用反射来验证这一点  如果是泛型擦除 那么List<String>的实际类型应该是List<Object>

List<String> list = new ArrayList<>();
list.add("这是String");
list.add("这也是String");
list.add("这还是String");

try {
    List.class.getMethod("add", Object.class).invoke(list, (Object) new int[] {1, 2, 3});
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
    e.printStackTrace();
}

for (Object obj : list)
{
    System.out.println(obj);
}

运行结果

这是String
这也是String
这还是String
[I@4554617c

于是我们在一个List<String>中成功插入了一个int数组

 

为什么java要使用泛型擦除机制来实现泛型

为了兼容旧版本代码

java的泛型是在J2 SE1.5中加入的 在此之前的通用容器都是将对象转为Object储存   List<T>编译后就成了List 完美兼容旧版本

但是这也带来了一些缺陷 泛型不能是基本类型 所有基本类型必须转为对应的包装类 例如List<Integer>  这个过程中产生了装箱 导致效率损失

听说之后版本的java会引入一些机制来解决基本类型装箱问题 但那可能得等到猴年马月了

 

END

以上是关于JAVA中的泛型用法一种: <T> 返回值用法。的主要内容,如果未能解决你的问题,请参考以下文章

java中的泛型

java中的泛型T和?的差异性,学习了

Java里的泛型加通配符的用法

Java中的泛型方法

Java中的泛型方法

Java中的泛型方法