资讯专栏INFORMATION COLUMN

是你眼中的泛型吗?

alphahans / 442人阅读

摘要:得出的结论是两个方法如果有相同的名称和特征签名,但返回值不同,那他们也是可以合法地共存于一个文件中的。同名方法参数个数顺序类型不同,与返回值类型无关。这是来自中的一个例子。

继《? extends T与? super T》之后,我们再聊聊泛型。

Demo 1
public interface Generator {
     T next();
}

第一种解决方法,在方法返回类型前加“”使其成为一个泛型方法。

public interface Generator {
    T next();
}

第二种解决方法,在接口名后加“”使其成为一个泛型接口。

泛型类/接口在使用前,必须先指名参数类型,其中除了泛型方法外的泛型参数都将是所指定的类型。如下:

// 泛型接口与其子类
public interface Generator {
    T next(T t);
    void print(T t);
}

public class SubGenerator implements Generator{

    @Override
    public String next(String t) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void print(String t) {
        // TODO Auto-generated method stub
        
    }

}

// 含有泛型方法的接口及其子类
public interface Generator {
    T next(T t);
     void print(U t);
}

public class SubGenerator implements Generator{

    @Override
    public String next(String t) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public  void print(U t) {
        // TODO Auto-generated method stub
        
    }

}
Demo 2

即静态方法无法访问泛型类上定义的泛型,此时采用泛型方法可解决。

// 正确做法
public class StaticGenerator {
    public static  T rebey(T t) {
        return null;
    }
}
Demo 3

在《深入理解Java虚拟机 JVM高级特性与最佳实践(高清完整版)》P271 介绍了“当泛型遇见重载”的例子。得出的结论是:

两个方法如果有相同的名称和特征签名,但返回值不同,那他们也是可以合法地共存于一个Class文件中的。

public String url(String s) {
    return "rebey.cn";
}

public int url(String s) {
    return 0;
}

然而以上代码是无法编译通过的。因为此书出版时还未发布JDK7,因此其实只有JDK1.6及以下才能编译通过。随着时间的推移,原来错的可能所以还是按我们原来的理解来解读重载就好了。同名方法参数个数、顺序、类型不同,与返回值类型无关。

Demo 4
public class Utilities {
    public static  HashSet create(int size) {
        return new HashSet(size);
    }
     
    public static void print( HashSet h) { 
        for (String s : h) System.out.println(s);
    }
}

public class ResultGerneric {
    public static void main(String[] args) {
        Utilities.print(Utilities.create(10));    // error in Java 5,6,7 ; fine in Java 8
    }
}

这是来自GenericsFAQ403中的一个例子。笔者在java7上测试了,如愿的看到了错误提示:“The method print(HashSet) in the type Utilities is not applicable for the arguments (HashSet)”。由于Utilities.create方法未指定具体类型,默认转为Object,所以Utilities.print此时无法接收其作为String类型的参数。而在Java8版本的增加了类型推断(type argument inference),能够根据赋值符号左边值类型自动推断出右边。

此外,通过显示指定参数类型也能够解决上述问题:

public class ResultGerneric {
    public static void main(String[] args) {
        Utilities.print(Utilities.create(10));//点操作符与方法名之间
    }
}

在《Think In Java》4th中泛型章节也提到了相似的例子(P363)。

说点什么

通过几个泛型的例子,我们看到:随着时间的推移,对的可能错,错的亦能对。

这不是很有趣的一件事吗?

待续...

更多有意思的内容,欢迎访问笔者小站: rebey.cn

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/67310.html

相关文章

  • Java™ 教程(泛型类型)

    泛型类型 泛型类型是通过类型参数化的泛型类或接口,修改以下Box类以演示此概念。 一个简单的Box类 首先检查一个对任何类型的对象进行操作的非泛型Box类,它只需要提供两个方法:set,它将一个对象添加到box中,get,它将检索它: public class Box { private Object object; public void set(Object object) ...

    Crazy_Coder 评论0 收藏0
  • Spring 中优雅的获取泛型信息

    摘要:今天我要分享的是在中优雅的获取泛型。通过反射获得定义中声明的父类的泛型参数的类型注意泛型必须定义在父类处这是唯一可以通过反射从泛型获得实例的地方如无法找到返回如工具从开始中添加了工具,这个类可以更加方便的用来回去泛型信息。 简介 Spring 源码是个大宝库,我们能遇到的大部分工具在源码里都能找到,所以笔者开源的 mica 完全基于 Spring 进行基础增强,不重复造轮子。今天我要分...

    Aldous 评论0 收藏0
  • 理解Java中泛型(一)

    摘要:参数化的类型其中是参数化的类型。类型参数的实例或实际类型参数其中是类型参数的实例或实际类型参数。它们并没有重载,而且泛型中也不存在重载这一说法。除此之外,我们应该尽量地多用泛型方法,而减少对整个类的泛化,因为泛型方法更容易把事情说明白。 泛型是适用于许多许多的类型 ---《JAVA编程思想》 在Java的面向对象编程过程中, 或许你知道运用继承、接口等一系列面向对象的动作来实现代码复用...

    YFan 评论0 收藏0
  • 浅析Java泛型

    摘要:泛型类在类的申明时指定参数,即构成了泛型类。换句话说,泛型类可以看成普通类的工厂。的作用就是指明泛型的具体类型,而类型的变量,可以用来创建泛型类的对象。只有声明了的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。 什么是泛型? 泛型是JDK 1.5的一项新特性,它的本质是参数化类型(Parameterized Type)的应用,也就是说所操作的数据类型被指定为一个参数,...

    godiscoder 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<