Java学习点滴——泛型
基于《Java编程思想》第四版
前言
虽然Java的泛型在语法上和C++相比是类似的,但在实现上两者是全然不同的。
语法
Java只需要一个<>就可定义泛型。在<>中可以使用任意符合Java语法要求的字符作为类型的标识,可以定义泛型类、泛型接口、泛型方法等。
class A<T>{
T a;
public <Q> void foo(Q a){
}
}
interface B<T>{
void foo(T a);
}
实现
Java的泛型并不像C++那样是在编译时根据需要按照模板实例化对应的类。比如下面这段C++代码,会以A为模板实例化两个类。
template<typename T>
class A
{
public:
A(){}
T a;
};
int main()
{
A<int> a;
A<float> b;
return 0;
}
查看汇编可以证实,调用的是两个不同类的构造函数
0x0000000000400545 <+15>: callq 0x40056c <A<int>::A()>
0x0000000000400551 <+27>: callq 0x400578 <A<float>::A()>
Java中所有类都继承自Object,任意类对象都可以向上转型后,使用Object变量存储其引用。基于这一点,Java的泛型实现时其实只有一种类型。以下两个类实际是等同的
class A<T>{
T a;
}
class A{
Object a;
}
当使用反射机制获取泛型类的信息时,可以发现class A<T>实际就是class A
public static void main(String[] args) {
A<Integer> a = new A();
Field[] f = a.getClass().getDeclaredFields();
System.out.println(Arrays.toString(f));
}
// 输出为 [java.lang.Object A.a]
由此我们也可以知道为什么下面这段代码总是输出same class
public static void main(String[] args) {
A<Integer> a = new A();
A<Double> b = new A();
if( a.getClass() == b.getClass() ){
System.out.println("same class");
}
}
因为基础类型并不继承自Object,所以Java的泛型是不支持基础类型的。如果这么做了,就会得到一个错误提示Type argument cannot be of primitive type。
自限定类型
因为使用泛型时,其类型参数会被当做Object来处理,所以编译器就无法感知真实类型的方法了。
比如下面这段代码,就无法通过编译
class A{
public void foo(){
System.out.println("A.foo()");
}
}
class B<T>{
T a;
B(T a){
this.a = a;
}
public bar(){
a.foo(); // 此处会提示编译错误,Object类型不存在foo()方法
}
}
此时必须将泛型类B的类型参数做限定,让编译器能从限定中获取到足够的信息去判断类型参数是存在foo()方法的。
class B<T extends A>{
T a;
B(T a){
this.a = a;
}
public bar(){
a.foo();
}
}
Java学习点滴——泛型的更多相关文章
- Java学习之——泛型
1.概要 generics enable types (classes and interfaces) to be parameters when defining classes, interfac ...
- 5 Java学习之 泛型
1. 基本概念 泛型是Java SE 1.5的新特性,泛型的本质是 参数化类型 ,也就是说所操作的 数据类型 被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为 ...
- Java学习笔记--泛型
一个泛型类就是具有一个或者多个类型变量的类. 我们可以只关注泛型,而不会为数据存储的细节而烦恼 . java泛型(一).泛型的基本介绍和使用 http://blog.csdn.net/lonelyro ...
- Java学习笔记——泛型
假定T不仅要指定接口的类继承.使用下面的方式: public class some<T extends Iterable<T> & Comparable<T>&g ...
- Java学习点滴——初识Java
基于<Java编程思想>第四版 前言 "程序就是算法加数据结构",而算法就是控制语句加操作符,编写一个程序就是使用控制语句加操作符去操作数据结构,因此我从Java的控制 ...
- JAVA学习之泛型
ArrayList<E>类定义和ArrayList<Integer>类引用中涉及的术语:1.整个ArrayList<E>称为泛型类型 2.ArrayList< ...
- Java学习之泛型和异常
泛型 1,设计原则或目的:只要代码在编译的时候没有错误,就不会抛异常. 2,泛型通配符 :类型通配符一般是使用 ? 代替具体的类型实参.注意了,此处是类型实参,而不是类型形参!相当于(父类作用)L ...
- Java学习之==>泛型
一.什么是泛型 泛型,即“参数化类型”,在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型.也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类.接口 ...
- Java学习_泛型
什么是泛型. Java标准库提供的ArrayList内部就是一个Object[]数组,配合存储一个当前分配的长度,就可以充当"可变数组". public class ArrayLi ...
随机推荐
- vue+axios访问本地json数据踩坑点
当我们想在vue项目中模拟后台接口访问json数据时,我们发现无论如何也访问不到本地的json数据. 注意:1.在vue-cli项目中,我们静态资源只能放在static文件夹中,axios使用get请 ...
- .net core Entity Framework 与 EF Core
重点讲 Entity Framework Core ! (一)Entity Framework 它是适用于.NET 的对象关系映射程序 (ORM),现在的EF6已经是久经沙场,并经历重重磨难,获得一致 ...
- 分布式日志框架Exceptionless之生产环境部署步骤
Exceptionless 是一个开源的实时的日志收集框架,它将日志收集变得简单易用并且不需要了解太多的相关技术细节及配置.本篇基于我的上一篇<基于Exceptionless实现分布式日志> ...
- Python爬虫入门这一篇就够了
何谓爬虫 所谓爬虫,就是按照一定的规则,自动的从网络中抓取信息的程序或者脚本.万维网就像一个巨大的蜘蛛网,我们的爬虫就是上面的一个蜘蛛,不断的去抓取我们需要的信息. 爬虫三要素 抓取 分析 存储 基础 ...
- 使用github pages搭建个人博客
一.环境准备 使用Github Pages搭建个人博客,一劳永逸,可以让我们更加专注于博客的撰写.博客的更新是通过将新建或改动的博客放在指定文件夹并推送到远程Github仓库来完成的,所以我们本地需要 ...
- clang如何获得程序控制流图
在低版本的clag中,可以直接clang -cc1 -analyze -cfg-dump 1.c来获得程序控制流图,但较高版本后就不行了 另外clang -cc1默认仅限当前目录,所以会出现fata ...
- MaxCompute 2.0复杂数据类型之array
1. 含义 类似于Java中的array.有序.可重复. 2. 场景 什么样的数据,适合使用array类型来存储呢?这里列举了几个我在开发中实际用到的场景. 2.1 标签类的数据 为什么说标签类数据适 ...
- 简述private,protected,public,internal修饰符的访问权限
private:私有成员,在类的内部才可以访问 protected:保护成员,在类的内部和继承类中可以访问 public:公共成员,完全公开,没有访问限制 internal:当前程序集内可以访问
- 将展示内容(div、iframe)放在Expand控件中
Expand是ArcGIS JavaScript API 4.3推出的一个widget(控件),用于承载一个HTML DOM元素,可以把一个自己编写的div或者是一个其他的Esri widget控件放 ...
- 2019-01-29 VS Code创建自定义Python代码片段
续前文[日常]Beyond的歌里最多是"唏嘘"吗? - Python分词+词频最后的想法, 发现VS Code支持用户自定义代码片段: Creating your own snip ...