赣州网站建设顺企网,免费销售网站模板下载安装,设计模板图,如何在电网网站做备案文章目录 java面向对象重点总结类与实例构造方法方法重载属性与修饰符封装继承多态重构抽象类接口抽象类和接口的区别#xff1a;集合泛型 java面向对象重点总结
对象是一个自包含的实体#xff0c;用一组可识别的特性和行为来标识。
面向对象编程#xff0c;英文叫Object… 文章目录 java面向对象重点总结类与实例构造方法方法重载属性与修饰符封装继承多态重构抽象类接口抽象类和接口的区别集合泛型 java面向对象重点总结
对象是一个自包含的实体用一组可识别的特性和行为来标识。
面向对象编程英文叫Object-Oriented ProgrammingOOP其实就是针对对象来进行编程的意思。
类与实例
类就是具有相同的属性和功能的对象的抽象的集合。我们来看代码 这里’class’是表示定义类的关键字Cat’就是类的名称shout’就是类的方法。
这里有两点要注意
1类名称首字母记着要大写。多个单词则各个首字母大写
2对外公开的方法需要用’public’修饰符。
应用一个类只要将类实例化一下就可以了。
实例就是一个真实的对象。比如我们都是’人’而你和我其实就是’人’类的实例了。而实例化就是创建对象的过程使用new关键字来创
建。 注意Cat cat new Cat其实做了两件事 Cat 实 例 化 后 等 同 于 出 生 了 一 只 小 猫 cat 此 时 就 可 以 让 小 猫cat.shout了。在任何需要小猫叫的地方都可以实例化它。
构造方法
构造方法又叫构造函数其实就是对类进行初始化。构造方法与类同名无返回值也不需要void在new的时候调用。
所有类都有构造方法如果你不编码则系统默认生成空的构造方法若你有定义的构造方法那么默认的构造方法就会
失效了。
也就是说由于你没有在Cat类中定义过构造方法所以Java语言会生成一个空的构造方法Cat。当然这个空的方法什么也不做只是为了让你能顺利地实例化而已。
构造方法是为了对类进行初始化。比如我们希望每个小猫一诞生就有姓名那么就应该写一个有参数的构造方法 这样一来我们在客户端要生成小猫时就必须要给小猫起名字了 结果显示 方法重载
方法重载提供了创建同名的多个方法的能力但这些方法需使用不同的参数类型。注意并不是只有构造方法可以重载普通方法也是可以重载的。 注意方法重载时两个方法必须要方法名相同但参数类型或个数必须要有所不同否则重载就没有意义了
方法重载可在不改变原方法的基础上新增功能。
方法重载算是提供了函数可扩展的能力。比如刚才这个例子有的小猫起好名字了就用带string参数的构造方法有的没有名字
就用不带参数的这样就达到了扩展的目的。
如果我需要分清楚猫的姓和名还可以再重载一个public Catstring firstNamestring lastName
属性与修饰符
属性是一个方法或一对方法即属性适合于以字段的方式使用方法调用的场合。这里还需要解释一下字段的意思字段是存储类要满足其设计所需要的数据字段是与类相关的变量。比如刚才的Cat类中的’private string name name其实就是一个字段它通常是私有的类变量。那么属性是什么样呢我们现在增加一个猫叫次数ShoutNum的属性。 Java中的访问修饰符用于控制类、变量、方法和构造方法的访问权限。Java支持四种不同的访问修饰符
public对所有类可见。protected对同一包内的类可见对子类可见对其他包的类不可见。default即缺省无修饰符对同一包内的类可见对其他包的类不可见。private只对同一类内可见。
以下是一些使用这些修饰符的示例
public class MyClass {public int publicField; // 公开访问protected int protectedField; // 保护访问int defaultField; // 默认包访问private int privateField; // 私有访问public void myMethod() { // 公开访问// 方法体}protected void myProtectedMethod() { // 保护访问// 方法体}void myDefaultMethod() { // 默认包访问// 方法体}private void myPrivateMethod() { // 私有访问// 方法体}
}通常字段都是private即私有的变量而属性都是public即公有的变量。那么在这里shoutNum就是私有的字段而ShoutNum
就是公有的对外属性。由于是对外的所以属性的名称一般首字母大写而字段则一般首字母小写或前加’_。
属性有两个方法get和set。get返回与声明的属性相同的数据类型表示的意思是调用时可以得到内部字段的值或引用set有一个参数用关键字value表示它的作用是调用属性时可以给内部的字段或引用赋值.
这就好像我们的房子我们并不希望房子是全透明的那样你在家里的所有活动全部都被看得清清楚楚毫无隐私可言。通常我们的房子有门有窗但更多的是不透明的墙。这门和窗其实就是public而房子内的东西其实就是private。而对于这个房子来说门窗是可以控制的我们并不是让所有的人都可以从门随意进出也不希望蚊子苍蝇来回出入。这就是属性的作用了如果你把字段声明为public那就意味着不设防的门窗任何时候调用者都可以读取或写入这是非常糟糕的一件事。如果把对外的数据写成属性那情况就会好
很多。 这就好比给窗子安装了纱窗只让阳光和空气进入而蚊子苍蝇就隔离。多了层控制就多了层保护。
由于有了’叫声次数’的属性于是我们的shout方法就需要改进了: “此时调用的时候只需要给属性赋值就可以了” 结果显示 如果我们不给属性赋值小猫会叫’喵’应该是三声因为字段shoutNum的初始值是3。
另外需要强调的是变量私有的叫字段公有的是属性那么对于方法而言同样也就有私有方法和公有方法了一般不需要对外界公开的方法都应该设置其修饰符为private私有。这才有利于’封装’。
封装
现在我们可以讲面向对象的三大特性之一’封装’了。每个对象都包含它能进行操作所需要的所有信息这个特性称为封装因此对象不必依赖其他对象来完成自己的操作。这样方法和属性包装在类中通过类的实例来实现。
封装有很多好处。第一良好的封装能够减少耦合至少我们让Cat和Form1的耦合分离了。第二类内部的实现可以自由地修改这也是显而易见的我们已经对Cat做了很大的改动。第三类具有清晰的对外接口这其实指的就是定义为public的ShoutNum属性和shout方法。
封装的好处很好理解比如刚才举的例子。我们的房子就是一个类的实例室内的装饰与摆设只能被室内的居住者欣赏与使用如果
没有四面墙的遮挡室内的所有活动在外人面前一览无遗。由于有了封装房屋内的所有摆设都可以随意地改变而不用影响他人。然而
如果没有门窗一个包裹得严严实实的黑箱子即使它的空间再宽阔也没有实用价值。房屋的门窗就是封装对象暴露在外的属性和方法专门供人进出以及流通空气、带来阳光。 现在我需要增加一个狗叫的功能就是加一个按钮’狗叫’单击后会弹出’我的名字叫XX汪汪汪’如何做
很简单仿造Cat加一个Dog类。然后再用类似代码调用就好了 但你有没有发现Cat和Dog有非常类似的代码90%的代码是一样的代码有大量重复不会是什么好事情。我们要用到面向
对象的第二大特性’继承’。
继承
我们还是先离开软件编程来想想我们的动物常识猫和狗都是动物准确地说他们都是哺乳动物。哺乳动物有什么特征
哺乳动物是胎生、哺乳、恒温的动物因为猫和狗是哺乳动物所以猫和狗就同样具备胎生、哺乳、恒温的特征。所以我们可以这样说由于猫和狗是哺乳动物所以猫和狗与哺乳动物是继承关系。
回到编程上对象的继承代表了一种’is-a’的关系如果两个对象A和B可以描述为’B是A’则表明B可以继承A。‘猫是哺乳动物’就说
明了猫与哺乳动物之间是继承与被继承的关系。实际上继承者还可以理解为是对被继承者的特殊化因为它除了具备被继承者的特性外还具备自己独有的个性。例如猫就可能拥有抓老鼠、爬树等’哺乳动物’对象所不具备的属性。因而在继承关系中继承者可以完全替换被继承者反之则不成立。所以我们在描述继承的’is-a’关系时是不能相互颠倒的。说’哺乳动物是猫’显然有些莫名其妙。继承定义了类如何相互关联共享特性。继承的工作方式是定义父类和子类或叫作基类和派生类其中子类继承父类的所有特性。子类不但继承了父类的所有特性还可以定义新的特性。
学习继承最好是记住三句话如果子类继承于父类第一子类拥有父类非private的属性和功能第二子类具有自己的属性和功能即子类可以扩展父类没有的属性和功能第三子类还可以以自己的方式实现父类的功能方法重写。
对比观察Cat和Dog类 我们会发现大部分代码都是相同的所以我们现在建立一个父类动物Animal类显然猫和狗都是动物。我们把相同的代码尽量放到动物类中。 然后我们需要写Cat和Dog的代码。让它们继承Animal。这样重复的部分都可以不用写了不过在Java中子类从它的父类中继承的成员
有方法、属性等但对于构造方法有一些特殊它不能被继承只能被调用。对于调用父类的成员可以用super关键字。 此时客户端的代码完全一样没有受到影响但重复的代码却因此减少了。
如果现在需要加牛、羊、猪等多个类似的类按你以前的写法就需要再复制三遍也就是有五个类。如果我们需要改动起始的叫声次数也就是让shoutNum由3改为5那需要改5个类现在有了Animal就只要改一个类就行了继承可以使得重复减少。 不用继承的话如果要修改功能就必须在所有重复的方法中修改代码越多出错的可能就越大而继承的优点是继承使得所有
子类公共的部分都放在了父类使得代码得到了共享这就避免了重复另外继承可使得修改或扩展继承而来的实现都较为容易。
继承是有缺点的那就是父类变则子类不得不变。另外继承会破坏包装父类实现细节暴露给子类这其实是增大了两个类之间的耦合性。
耦合性简单理解就是藕断丝连两个类尽管分开但如果关系密切一方的变化都会影响到另一方这就是耦合性高的表现继
承显然是一种类与类之间强耦合的关系。当两个类之间具备**‘is-a’**的关系时就可以考虑用继承了。
多态
下面我们再来增加需求如果我们要举办一个动物运动会来参加的有各种各样的动物其中有一项是’叫声比赛’。界面就是放两个按钮一个是’动物报名’就是确定动物的种类和报名的顺序另一个是’叫声比赛’就是报名的动物挨个地叫出声音来比赛。注意来报名的都是什么动物我们并不知道。可能是猫、可能是狗也可能是其他的动物当然它们都需要会叫才行。
先分析一下来报名的都是动物参加叫声比赛必须会叫。这说明什么说明都有叫的方法也就是Animal类中有shout方法。
所谓的’动物报名’其实就是建立一个动物对象数组让不同的动物对象加入其中。所谓的’叫声比赛’其实就是遍历这个数组来让动物
们’shout就可以了。
就之前讲到的知识是不足以解决这个问题的所以我们引入面向对象的第三大特性——多态 同样是鸟同样展开翅膀的动作但老鹰、鸵鸟和企鹅之间是完全不同的作用。老鹰展开翅膀用来更高更远地飞翔鸵鸟用来更快更稳地奔跑而企鹅则是更急更流畅地游泳。这就是生物多态性表现。在面向对象中多态表示不同的对象可以执行相同的动作但要通过它们自己的实现代码来执行 看定义显然不太明白我再来举个例子。我们的国粹’京剧’以前都是子承父业代代相传的艺术。假设有这样一对父子父亲是非常有名的京剧艺术家儿子长大成人模仿父亲的戏也惟妙惟肖。有一天父亲突然发高烧上不了台表演而票都早就卖出退票显然会大大影响声誉。怎么办呢由于京戏都是需要化妆才可以上台的于是就决定让儿子代父亲上台表演。
化妆后谁认识谁呀只要唱得好就可以糊弄过去了。
这里面有几点注意第一子类以父类的身份出现儿子代表老子表演化妆后就是以父亲身份出现了。第二子类在工作时以自己的方式来实现儿子模仿得再好那也是模仿儿子只能用自己理解的表现方式去模仿父亲的作品第三子类以父类的身份出现时子类特有的属性和方法不可以使用儿子经过多年学习其实已经有了自己的创作自己的绝活但在此时代表父亲表演时绝活是不能表现出来的。当然如果父亲还有别的儿子会表演也可以在此时代表父亲上场道理也是一样的。这就是多态。 子类可以选择使用override关键字将父类实现替换为它自己的实现这就是方法重写
Override或者叫作方法覆写。我们来看一下例子
由于Cat和Dog都有shout的方法只是叫的声音不同所以我们可以让Animal有一个shout的方法然后Cat和Dog去重写这个shout用的时候就可以用猫或狗代替Animal叫唤来达到多态的目的。 再回到刚才写的客户端代码上 结果显示先单击动物报名然后叫声比赛将有五个对话列出 Animal相当于京剧表演的老爸Cat和Dog相当于儿子儿子代表父亲表演shout但Cat叫出来的是’喵’Dog叫出来的是’汪’这就是所
谓的不同的对象可以执行相同的动作但要通过它们自己的实现代码来执行。
不过一定要注意了这个对象的声明必须是父类而不是子类实例化的对象是子类这才能实现多态。多态的原理是当方法被调用时无论对象是否被转换为其父类都只有位于对象继承链最末端的方法实现会被调用。也就是说虚方法是按照其运行时类型而非编译时类型进行动态绑定调用的。 重构
现在又来了小牛和小羊来报名需要参加’叫声比赛’如何做我现在再实现牛Cattle和羊Sheep的类让它们都继承
Animal就可以了。 有没有发现猫狗牛羊四个类除了构造方法之外shout里除了四种动物叫的声音不同外几乎没有任何差异。
所以这里有重复我们还是应该要改造它
我先把重复的这个shout的方法体放到Animal类中把叫的声音部分改成另一个方法getShoutSound。 此时的子类就极其简单了。除了叫声和构造方法不同所有的重复都转移到了父类真是漂亮之极。 子类拥有所有父类非private的属性和方法。由于子类继承父类所以是public的Shout方法是一定可以为所有子类所用的。这里其实就是在用一个设计模式叫模板方法
抽象类
我们再来观察你会发现Animal类其实根本就不可能实例化的你想呀说一只猫长什么样可以想象说new Animal即
实例化一个动物。一个动物长什么样动物是一个抽象的名词没有具体对象与之对应。 所以我们完全可以考虑把实例化没有任何意义的父类改成抽象类同样地对于Animal类的getShoutSound方法其实方法体没有任何意义所以可以将修饰符改为abstract使之成为抽象方法。Java允许把类和方法声明为abstract即抽象类和抽象方法。 这样一来Animal就成了抽象类。抽象类需要注意几点第一抽象类不能实例化刚才就说过动物’实例化是没有意义的第二抽象方法是必须被子类重写的方法不重写的话它的存在又有什么意义呢其实抽象方法可以被看成是没有实现体的虚方法第三如果类中包含抽象方法那么类就必须定义为抽象类不论是否还包含其他一般方法。
这么说的话一开始就可以把Animal类设成抽象类了根本没有必要存在虚方法的父类。我们应该考虑让抽象类拥有尽可能多的共同代码拥有尽可能少的数据。
抽象类通常代表一个抽象概念它提供一个继承的出发点当设计一个新的抽象类时一定是用来继承的所以在一个以继承关系形成的等级结构里面树叶节点应当是具体类而树枝节点均应当是抽象类。也就是说具体类不是用来继承的。我们作为编程设计者应该要努力做到这一点。比如若猫、狗、牛、羊是最后一级那么它们就是具体类但如果还有更下面一级的金丝猫继承于猫、哈巴狗继承于狗就需要考虑把猫和狗改成抽象类了当然这也是需要具体情况具体分析的。 接口
在动物运动会里还有一项非常特殊的比赛是为了给有特异功能的动物展示其特殊才能的。可以来比赛的比如有机器猫叮当 、石猴孙悟空、肥猪猪八戒再比如蜘蛛人、蝙蝠侠等。其实我的目的只是为了让两个动物尽量不相干而已。现在叮当会从肚皮的口袋里变出东西而孙悟空可以拔根毫毛变出东西且有七十二般变化八戒有三十六般变化。它们各属于猫、猴、猪现在需要让它们比赛谁变东西的本领大。来分析一下如何做 变出东西’应该是叮当 、孙悟空、猪八戒的行为方法要想用多态就得让猫、猴、猪有’变出东西’的能力而为了更具有普遍意义干脆让动物具有’变出东西’的行为这样就可以使用多态了。
这犯了几乎所有学面向对象的人都会犯的错误变出东西’它是动物的方法吗如果是那是不是所有的动物都必须具备’变出东西’的能力呢这其实只是三个特殊动物具备的方法。
这时候我们就需要新的知识了那就是接口interface。通常我们理解的接口可能更多的是像电脑、音响等设备的硬件接口比如用来传输电力、音视频、数据等接线的插口。而今天我们要提的是面向对象编程里的接口概念。
接口是把隐式公共方法和属性组合起来以封装特定功能的一个集合。一旦类实现了接口类就可以支持接口所指定的所有属性和成员。声明接口在语法上与声明抽象类完全相同但不允许提供接口中任何成员的执行方式。所以接口不能实例化不能有构造方法和字段不能有修饰符比如public、private等不能声明为虚拟的或静态的等。还有实现接口的类就必须要实现接口中的所有方法和属性。
一个类可以支持多个接口多个类也可以支持相同的接口。所以接口的概念可以让用户和其他开发人员更容易理解其他人的代
码。接口的命名有些语言前面要加一个大写字母’I’这是一种规范。 我们先创建一个接口它是用来’变东西’的。注意接口用interface声明而不是class接口名称前加’I’会更容易识别接口中的方法或属性前面不能有修饰符、方法没有方法体。 猴子的类Monkey和孙悟空的类StoneMonkey与上面非常类似在此省略。此时我们的客户端可以加一个’变出东西’按钮并实现下面的代码 结果显示 其实这和抽象类是很类似的由于我现在要让两个完全不相干的对象叮当和孙悟空来做同样的事情’变出东西’所以我不得不让
他们去实现做这件’变出东西’的接口这样的话当我调用接口的’变出东西’的方法时程序就会根据我实现接口的对象来做出反应如果是叮当就是用万能口袋如果是孙悟空就是七十二变利用了多态性完成了两个不同的对象本不可能完成的任务。
同样是飞鸟用翅膀飞飞机用引擎加机翼飞而超人呢举起两手握紧拳头就能飞它们是完全不同的对象但是如果硬要
把它们放在一起的话用一个飞行行为的接口比如命名为IFly的接口来处理就是非常好的办法。 抽象类和接口的区别
从表象上来说抽象类可以给出一些成员的实现接口却不包含成员的实现抽象类的抽象成员可被子类部分实现接口的成员需要实现类完全实现一个类只能继承一个抽象类但可实现多个接口等。但这些都是从两者的形态上去区分的。我觉得还有三点是能帮助我们去区分抽象类和接口。第一类是对对象的抽象抽象类是对类的抽象接口是对行为的抽象。接口是对类的局部行为进行的抽象而抽象类是对类整体字段、属性、方法的抽象。如果只关注行为抽象那么也可以认为接口就是抽象类。总之不论是接口、抽象类、类甚至对象都是在不同层次、不同角度进行抽象的结果它们的共性就是抽象。第二如果行为跨越不同类的对象可使用接口对于一些相似的类对象用继承抽象类。比如猫呀狗呀它们其实都是动物它们之间有很多相似的地方所以我们应该让它们去继承动物这个抽象类而飞机、麻雀、超人是完全不相关的类叮当是动漫角色孙悟空是古代神话人物这也是不相关的类但它们又是有共同点的前三个都会飞而后两个都会变出东西所以此时让它们去实现相同的接口来达到我们的设计目的就很合适了。其实实现接口和继承抽象类并不冲突我完全可以让超人继承人类再实现飞行接口。 超人除了内裤外穿以外基本就是一个正常人的样子让他继承人类是对的但他本事很大除了飞天他还具有刀枪不入、力大无穷等非常人的能力而这些能力也可能是其他对象具备的所以就让超人去实现飞行、力大无穷等行为接口这就可以让超人和飞机比飞行和大象比力气了这就是一个类只能继承一个抽象类却可以实现多个接口的做法。第三从设计角度讲抽象类是从子类中发现了公共的东西泛化出父类然后子类继承父类而接口是根本不知子类的存在方法如何实现还不确认预先定义。这里其实说明的是抽象类和接口设计的思维过程。回想一下我们今天刚开始讲的时候先是有一个Cat类然后再有一个Dog类观察后发现它们有类似之处于是泛化出Animal类这也体现了敏捷开发的思想通过重构改善既有代码的设计。事实上只有小猫的时候你就去设计一个动物类这就极有可能会成为过度设计了。所以说抽象类往往都是通过重构得来的当然如果你事先意识到多种分类的可能那么事先就设计出抽象类也是完全可以的。 而接口就完全不是一回事。我们很早已经设计好了电源插座的接口但在几十年前是无法想象未来会有什么样的电器需要电源插座的。只要事先把接口设计好剩下的事就慢慢再说不着急了。 再比如我们是动物运动会的主办方在策划时大家坐在一起考虑需要组织什么样的比赛。大家商议后觉得应该设置如跑得最快、跳得最高、飞得最远、叫得最响、力气最大等比赛项目。此时主办方其实还不太清楚会有什么样的动物来参加运动会所有的这些比赛项目都可能是完全不相同的动物在比它们将如何去实现这些行为也不得而知此时能做的事就是事先定义这些比赛项目的行为接口。
抽象类是自底而上抽象出来的而接口则是自顶向下设计出来的。
集合
下面我们再来看看客户端的代码中‘动物报名’用的是Animal类的对象数组你设置了数组的长度为5也就是说最多只能有五个动物可以报名参加’叫声比赛’多了就不行了。这显然是非常不合理的应该考虑改进。
数组的优点比如说数组在内存中连续存储因此可以快速而容易地从头到尾遍历元素可以快速修改元素等。数组的缺点应该是创建时必须要指定数组变量的大小还有在两个元素之间添加元素也比较困难。
这就可能使得数组长度设置过大造成内存空间浪费长度设置过小造成溢出。所以Java提供了用于数据存储和检索的专用类这些类统称集合。这些类提供对堆栈、队列、列表和哈希表的支持。大多数集合类实现相同的接口。
我们现在介绍当中最常用的一种ArrayList。首先ArrayList是程序包java.util.ArrayList下的一部分它是使用大小可按需动态增加的数组实现Collection接口。
**ArrayList的容量是ArrayList可以保存的元素数。ArrayList的默认初始容量为0。随着元素添加到ArrayList中容量会根据需要通过重新分配自动增加。使用整数索引可以访问此集合中的元素。此集合中的索引从零开始。**可以这样理解数组的容量是固定的而ArrayList的容量可根据需要自动扩充。由于实现了Collection所以ArrayList提供添加、插入或移除某一范围元素的方法。下面我们来看看如何做 如果有动物报完名后由于某种原因如政治、宗教、兴奋剂、健康等放弃比赛此时应该需要将其从名单中移除。例如在报了名后两只小狗需要退出比赛。我们查了一下它们的报名索引次序为1和2从0开始计算所以可以应用集合的remove方法它的作用是移除指定索引处的集合项。 集 合 与 数 组 的 不 同 就 在 于 此 程 序 在 执 行RemoveAt1的时候也就是叫’阿毛’的Dog被移除了集合此时’小黑’的索引次序还是原来的2吗等于整个后序对象都向前移一位了。应该是这样才对。也就是说集合的变化是影响全局的它始终都保证元素的连续性。 总结一下集合ArrayList相比数组有什么好处
主要就是它可以根据使用大小按需动态增加不用受事先设置其大小的控制。还有就是可以随意地添加、插入或移除某一范围元素比数组要方便。
这是ArrayList的优势但它也有不足ArrayList不管你是什么对象 都 是 接 受 的 因 为 在 它 眼 里 所 有 元 素 都 是 Object 这 就 使 得 如 果你 ‘arrayAnimal.add 123 ’ 或 者 arrayAnimal.add HelloWorld在编译时都是没有问题的但在执行时forAnimal itemarrayAnimal需要明确集合中的元素是Animal类型而123是整型HelloWorld是字符串型这就会在运行到此处时报错显然这是典型的类型不匹配错误换句话说ArrayList不是类型安全的。还有就是ArrayList对于存放值类型的数据比如int、string型string是一种拥有值类型特点的特殊引用类型或者结构struct的数据用ArrayList就意味着都需要将值类型装箱为Object对象使用集合元素时还需要执行拆箱操作这就带来了很大的性能损耗。
所谓装箱就是把值类型打包到Object引用类型的一个实例中。比如整型变量i被’装箱’并赋值给对象o。
所谓拆箱就是指从对象中提取值类型。此例中对象o拆箱并将其赋值给整型变量i。 相对于简单的赋值而言装箱和拆箱过程需要进行大量的计算。对值类型进行装箱时必须分配并构造一个全新的对象。其次拆箱所需的强制转换也需要进行大量的计算MSDN。总之装箱拆箱是耗资源和时间的。而ArrayList集合在使用值类型数据时其实就是在不断地做装箱和拆箱的工作这显然是非常糟糕的事情。
Java在5.0版之前的确也没什么好办法但5.0出来后就推出了新的技术来解决这个问题那就是泛型。
泛型
泛型是具有占位符类型参数的类、结构、接口和方法这些占位符是类、结构、接口和方法所存储或使用的一个或多个类型的占位符。泛型集合类可以将类型参数用作它所存储的对象的类型的占位符类型参数作为其字段的类型和其方法的参数类型出现。我读给你的是泛型定义的原话听起有些抽象我们直接来看例子。在Java 5.0后有ArrayList类的泛型等效类该类使用大小可按需动态增加的数组实现Collection泛型接口。其实用法上关键就是在ArrayList后面加’这个’T’就是你需要指定的集合的数据或对象类型。 此 时 如 果 你 再 写 ‘arrayAnimal.add 123 ’ 或者’arrayAnimal.addHelloWorld结果将是编译报错因为add的参数必须是要Animal或者Animal的子类型才行。
我是这样想的其实ArrayList和ArrayList在功能上是一样的不同点就在于它在声明和实例化时都需要指定其内部项的数据或对象类型这就避免了刚才讲的类型安全问题和装箱拆箱的性能问题了。
不过显然Java语言的设计者也并不是一开始就明白这一点也是通过实践和用户的反馈才在Java 5.0版中改进过来的。巨人也会有走弯路的时候何况我们常人。通常情况下都建议使用泛型集合因为这样可以获得类型安全的直接优点而不需要从基集合类型派生并实现类型特定的成员。此外如果集合元素为值类型泛型集合类型的性能通常优于对应的非泛型集合类型并优于从非泛型基集合类型派生的类型因为使用泛型时不必对元素进行装箱。