java参数传入的是一个类名_Java编程细节——泛型的定义(类、接口、对象)、使用、继承...

1. 设计泛型的初衷:

1) 主要是为了解决Java容器无法记忆元素类型的问题:

i. 由于Java设计之初并不知道会往容器中存放什么类型的元素,因此元素类型都设定为Object,这样就什么东西都能放了!

ii. 但是这样设计有明显的缺点:

a. 取出元素的时候必须进行强制类型转换(尽管集合在运行时里面元素的“运行时类型”不变,即元素的getClass返回的还是最初自己的类型而不是Object);

b. 如果不小心往集合里加了不相同类型的元素可能会导致类型异常(进行equals、compare比较的时候尤为明显);

c. 由于没有类型就需要在很多地方进行强制类型转换,但是这样做增加了编程的复杂度,并且代码也不美观(臃肿),维护起来也更加困难;

2) 泛型的概念定义:

i. 从Java 5开始,引入了参数化类型(Parameterized Type)的概念,改造了所有的Java集合,使之都实现泛型,允许程序在创建集合时就可以指定集合元素的类型,比如List就表名这是一个只能存放String类型的List;

ii. 泛型(Generic):就是指参数化类型,上面的List就是参数化类型,因此就是泛型,而String就是该List泛型的类型参数;

3) 泛型的好处:

i. 使集合可以记住元素类型,即取出元素的时候无需进行强制类型转化了,可以直接用原类型的引用接收;

ii. 一旦指定了性参数那么集合中元素的类型就确定了,不能添加其他类型的元素,否则会直接编译保存,这就可以避免了“不小心放入其他类型元素”的可能;

iii. 上述保证了如果在编译时没有发出警告,则在运行时就一定不会产生类型转化异常(ClassCastException);

iv. 显然,泛型使编程更加通用,并且代码也更加简洁,代码更加容易维护;

2. 创建泛型对象——自动类型推断的菱形语法:

1) 首先,定义泛型引用一定要使用尖括号指定类型参数,例如:List list、Map等,其中的String、Integer之类的就是类型参数;

2) 其次,使用构造器构造泛型对象的时候可以指定类型参数也可以不指定,例如:

i. List list = new List(); // 这当然是对的

ii. List list = new List<>(); // 这样对,因为List的类型参数可以从引用推断出!!!但是引用的类型参数是一定要加的,否则无法推断;

3) 由于<>很像菱形,因此上面的语法也叫做菱形语法;

4) 错误提示:引用无类型参数但构造器有类型参数的写法是不对的!例如,List list = new List();!!至于为什么不对,这会在泛型原理的章节中详细介绍,这里先记住这样写不对就行了!!反正就是一个原则,泛型引用是一定要指定类型参数的!!

5) 示例:af1d0c76445a8eb2275500cb6284c08c.png

3. 定义泛型类、接口:

1) 不仅Java的集合都定义成了泛型,用户自己也可以定义任意泛型的类、接口,只要在定义它们时用<>来指定类型参数即可;

2) 例如:public class Fruit { ... },其中指定了该泛型的类型参数,这个T是一个类型参数名,用户可以任意命名(就像方法参数的形参名一样),只有在定义该泛型的对象时将T替换成指定的具体类型从而产生一个实例化的泛型对象,例如:Fruit fruit = new Fruit<>(...);

3) 类型形参可以在整个接口、类体内当成普通类型使用,集合所有可使用普通类型的地方都可以使用类型形参,例如:773898fe525d2e30d0bcf11aaf4860f0.png

可以看到,在接口内/类体内甚至还可以使用该类型形参运用泛型!例如上面makeSet方法返回一个泛型Set;

4) 定义泛型构造器:泛型的构造器还是类名本身,不用使用菱形语法,例如:6aa8d8e165d7bdde1803316e9af2a35b.png

定义构造器无需MyGeneric(...) { ... }了,只有在new的时候需要用到菱形语法;

4. 实现/继承泛型接口/泛型类:

1) 定义泛型和使用泛型的概念:主要区别就是定义和使用

i. 那Java的方法做类比,Java的方法在定义的时候使用的都是形参(虚拟参数),但是在调用方法(使用方法)的时候必须传入实参;

ii. 同样泛型也有这个特点,泛型的类型参数和方法的参数一样,也是一种参数,只不过是一种特殊的参数,用来表示未知的类型罢了;

iii. 因此,泛型也是在定义的时候必须使用形参(虚拟参数,用户自己随意命名),但是在使用泛型的时候(比如定义泛型引用、继承泛型)就必须使用实参,而泛型的实参就是具体的类型,像String、Integer等具体的类型(当然也可以是自定义类型);

2) 泛型定义的时候使用形参,例如:public class MyGeneric { ... } // T就是一个自己随意命名的类型形参

3) 使用泛型的时候必须传入实参:

i. 定义引用(对象)的时候毫无疑问,肯定需要传实参:ArrayList list = ...; // 必须用具体的类型,像这里就是String来代替形参,即实参

ii. 实现/继承一个泛型接口/类的时候:

你在实现/继承一个接口/类的时候实际上是在使用该接口/类,比如:public class Son extends Father { ... }中Father这个类就是正在被使用,毫无疑问,必定是在使用;

因此泛型其实无法继承/实现,因为在实现/继承的时候必须为泛型传入类型实参,给定实参后它就是一个具体的类型了,就不再是泛型了

示例:public class MyType extends MyGeneric { ... } // implements、extends的时候必须传入类型实参,因为实在使用泛型。原则上,任何编程语言都不允许泛型模板层层继承!!

4) 继承之后,父类/接口中的所有方法中的类型参数都将变成具体的类型,你在子类中覆盖这些方法的时候一定要用具体的类型,不能继续使用泛型的类型形参了,例如:c4c40528685faca9bc674c11b5b07786.png

这一定能保证,这三个方法都是从父类中继承来的,只不过类型形参T被实例化成了String;

5. 泛型参数继承:

1) 上面派生出来的类不是泛型,是一个实体类型,因为其继承的泛型是具有类型实参的,而Java还支持一种特殊的语法,可以让你从泛型继续派生出泛型,而泛型的类型参数可以继续传承下去;

2) 语法如下:e94ee3ff7ae8a467494c7ef67ca2226c.png

即子泛型可以传承父泛型的泛型参数,那么在子类中泛型参数T就和父类的完全相同,还是照常使用(和父类一样正常使用);

3) 注意:

i. 这里extends Father了,因此父类泛型Father就是被使用了,而按照之前讲的规则,使用给一个泛型是必须要指定类型实参的!因此这里的这个语法是一种特殊语法,Java专门为这种语法开了后门,这种语法只有在类型参数传承的时候才会用到(即上面这种应用);

ii. 一旦使用了这种语法,就表示要进行类型参数的传承了(即父类的T传递给子类继续使用,因此子类也是一个跟父类一样的泛型);

iii. 并且一旦使用了这种语法,那么子类定义中的Son和extends Father中的类型参数必须和定义父类时的类型参数名完全一样!!

a. 以下三种情况全部错误(全部发生编译报错):8ea9fe7dace25d4da4906440905bdc3c.png

必须全部使用和父类定义相同的类型参数名(T)!才行,这是Java语法的特殊规定;

4) 其实Java容器中很多类/接口都是通过类型参数传承来定义的:

i. 最典型的例子就是:public interface List extends Collection { ... }

ii. 虽然"如果A是B的父类,但Generic不是Generic"的父类,但"如果A是B的父类,那A一定是B的父类"!这是一定的;

iii. 因为类型参数传承的定义方式本身就是:Son extends Father,那Father一定是Son的父类咯!

6. 在使用泛型的时候可以不使用菱形语法指定实参,直接裸用类型名:

1) 例如:

i. 定义引用(对象)时裸用类名:ArrayList list = new ArrayList(); // 当然也可以写成ArrayList list = new ArrayList<>();

ii. 实现/继承:public class MyType extends MyGeneric { ... }

上面使用的类型或者接口在定义的时候都是泛型!!但是使用它们的时候忽略类型参数(都不用加菱形);

2) Java规定,一个泛型无论如何、在任何地方、不管如何使用,它永远都是泛型,因此这里既是你忽略类型实参它底层也是一个泛型,那么它的类型实参会是什么呢?既然我们没有显式指定,那么Java肯定会隐式为其指定一个类型实参吧?

3) 答案是肯定的,如果使用泛型的时候不指定类型实参,那么Java就会用该泛型的“原生类型“来作为类型实参传入,那么“原生类型“是什么呢?这里先不介绍,会在下一章的”泛型原理“里详细分解;但是我们这里可以先透露一下,Java集合的原生类型基本都是Object,因此像上面的ArrayList list = new ArrayList();写法其实传入的是Object类型实参,即ArrayList!0f6f55bed80c38e67fc79f8e4bc277da.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/399143.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux环境下安装部署AWStats日志分析系统实例

AWStats是使用Perl语言开发的一款开放性日志分析系统&#xff0c;可分析Apache网站服务器的访问日志&#xff0c;还可以用来分析Samba、Vsftpd、IIS等日志信息。此文章主要讲解如何在linux系统下安装部署关于对Apache网站服务站日志分析的AWStats。实验步骤一&#xff0c;安装部…

HDU4911 Inversion 解题报告

题意&#xff1a;求逆序对 解题思路&#xff1a;1)树状数组 离散化 解题代码&#xff1a; 1 // File Name: a.cpp2 // Author: darkdream3 // Created Time: 2014年08月05日 星期二 12时05分09秒4 5 #include<vector>6 #include<list>7 #include<map>8 #inc…

springmvc的国际化

1&#xff1a;三个国际化资源文件 i18n.usernameUsername i18n.passwordPassword i18n.username\u7528\u6237\u540D i18n.password\u5BC6\u7801 i18n.usernameUsername i18n.passwordPassword 2&#xff1a;在spring中配置国际化资源文件 <!-- 配置国际化资源文件 --><…

.9-浅析webpack源码之NodeEnvironmentPlugin模块总览

介绍Compiler的构造比较无趣&#xff0c;不如先过后面的&#xff0c;在用到compiler的时候再做讲解。 这一节主要讲这行代码&#xff1a; // 不管这里 compiler new Compiler(); compiler.context options.context; compiler.options options; // 看这里 new NodeEnvironmen…

java单例模式的七种写法_Java设计模式之单例模式的七种写法

什么是单例模式&#xff1f;单例模式是一种常见的设计模式&#xff0c;单例模式的写法有很多种&#xff0c;这里主要介绍三种&#xff1a; 懒汉式单例模式、饿汉式单例模式、登记式单例 。单例模式有以下特点&#xff1a;1、单例类只能有一个实例。2、单例类必须自己创建自己唯…

Struts2国际化

一&#xff1a;简单理解 国际化简称i18n&#xff0c;其来源是英文单词 internationalization的首末字符i 和n。18为中间的字符数。 随着全球经济的一体化&#xff0c;软件开发者应该开发出支持多国语言、国际化的Web应用。对于Web应用来说&#xff0c;同样的页面在不同的语言环…

用Emacs编写mybatis

<?xml version"1.0" encoding"utf-8"?> 用Emacs编写mybatis用Emacs编写mybatis Table of Contents 1. 效果图2. 配置1 效果图 2 配置 现在web开发&#xff0c;最流行的orm框架非mybatis莫属了&#xff0c;它功能强大&#xff0c;编写简单灵活&…

java方法参数

Java程序设计语言总是采用值调用。也就是说&#xff0c;方法得到的是所有参数的一个拷贝&#xff0c;特别是方法不能修改传递给它的任何参数变量的内容。 基本类型参数 1&#xff09;X被初始化为percent值的一个拷贝&#xff1b; 2&#xff09;X被乘以3等于30。但是percent仍然…

SaltStack源码分析之:master端执行salt模块大致流程

2019独角兽企业重金招聘Python工程师标准>>> ##JOB执行流程 先看下官网对于master端的工作流程的介绍&#xff1a; The Salt master works by always publishing commands to all connected minions and the minions decide if the command is meant for them by ch…

myecplise新建Maven项目Filter选什么,使用myeclipse建立maven项目

myecplise新建Maven项目Filter选什么 使用myeclipse建立maven项目 1234567分步阅读maven是管理项目的&#xff0c;myeclipse是编写代码的。第一次写项目都要配置好多东西&#xff0c;很麻烦&#xff0c;now 来看看怎样新建一个maven项目。 工具/原料 myeclipsemaven方法/步骤 1…

关于TCP/IP与数据传输

一、TCP/IP的具体含义&#xff1a; 从字面意思来讲&#xff0c;很多人会认为TCP/IP是指TCP与IP这两种协议。有时确实也可以说是这两种协议&#xff0c;但是大部分情况下所说的是利用IP进行通信时所必须用到的协议群的统称。具体来说IP,ICMP,TCP,UDP,FTP以及HTTP等都属于TCP/IP协…

geohash php_空间索引-geohash算法实现

算法简介geohash是实现空间索引的一种算法,其他实现空间索引的算法有:R树和其变种GIST树、四叉树、网格索引等算法基本原理geohash算法将地球理解为一个二维平面&#xff0c;将平面递归分解成更小的子块&#xff0c;每个子块在一定经纬度范围内拥有相同的编码&#xff0c;这种方…

ActiveReports 报表控件V12新特性 -- 新增JSON和CSV导出

ActiveReports 报表控件V12新特性 -- 新增JSON和CSV导出 ActiveReports 是一款专注于 .NET 平台的报表控件&#xff0c;全面满足 HTML5 / WinForms / ASP.NET / ASP.NET MVC / WPF 等平台下报表设计和开发工作需求&#xff0c;作为专业的报表工具为全球超过 300,000 开发人员提…

php imap配置,怎么为PHP编译imap扩展?

为PHP编译imap扩展的方法&#xff1a;首先安装“imap-open2007e”&#xff1b;然后下载源代码&#xff1b;接着准备好系统的“imap-open”环境&#xff1b;最后进入“./ext/extension/imap/”文件夹下执行“make”命令即可。怎么为PHP编译imap扩展&#xff1f;最近为项目增加了…

vmware安装minimal centos报错/etc/rc5.d/s99local : line

2019独角兽企业重金招聘Python工程师标准>>> 有人用vmware安装minimal centos报错/etc/rc5.d/s99local : line:25 : eject : command not found 。我们看下完整报错内容&#xff1a; Installing VMware Tools, please wait...mount: special device /dev/hda does n…

后缀树(Suffix Trie)子串匹配结构

Suffix Trie 又称后缀Trie或后缀树。它与Trie树的最大不同在于&#xff0c;后缀Trie的字符串集合是由指定字符串的后缀子串构成的。比如、完整字符串"minimize"的后缀子串组成的集合S分…

java中的线程和进程,Java | 线程和进程,创建线程

一、线程与进程线程定义进程中执行的一个代码段&#xff0c;来完成不同的任务组成&#xff1a;线程ID&#xff0c;当前指令指针(PC)&#xff0c;寄存器集合(存储一部分正在执行线程的处理器状态的值)和堆栈进程定义执行的一段程序&#xff0c;一旦程序被载入到内存中准备执行就…

Maven的pom报错的解决方法

如果在MyEclipse里面导入项目,导入不了,如下图 接下来可以点击Import Maven Projects里的Action那一行Resolve Later. 点击Do Not Execute(add to pom)就可以正常导入了转载于:https://www.cnblogs.com/JimmySeraph/p/8068299.html

django零开始

2019独角兽企业重金招聘Python工程师标准>>> 安装。。。后查看 import django django.VERSION #输出版本号&#xff0c;目前自己是py2.7.9和django1.8 1&#xff0c;新建一个django-project django-admin.py startproject project-name 一个project一般为一个项目 …

关于Python3.6下登陆接口的尝试

编者按&#xff1a;README:此代码为用户登陆界面&#xff0c;添加了寻求帮助选项。1.学习了基本数据类型&#xff0c;string, int&#xff0c;以及while循环&#xff0c;continue, break, if, elif, else条件语句&#xff0c;“x".format&#xff08;x&#xff09;变量替代…