不可多得的干货!文末有福利!聪明人已经收藏了!

前言

前面也说了,
学习Netty的基础,那就是Nio,昨天我们简单的过了一下BIO,这是我们Java IO的基础,在JDK1.4之前的主要的io方式。
今天开始,我们就开始把NIO的一些东西了解清楚,之后才是Netty ,
因为我们的Netty是基础NIO的一个框架嘛,下面就来详细说说。

基本知识

1.学会分析源码

程序员每天都和代码打交道。经过数年的基础教育和职业培训,大部分程序员都会「写」代码,或者至少会抄代码和改代码。但是,会读代码的并不在多数,会读代码又真正读懂一些大项目的源码的,少之又少。这种怪状,真要追究起来,怪不得程序员这个群体本身 —— 它是两个原因造成的:

  • 我们所有的教育和培训都在强调怎么写代码,并没有教大家如何读代码

  • 大多数工作场景都是一个萝卜一个坑,我们只需要了解一个系统的局部便能开展工作,读不相干的代码,似乎没用

读源码三问:“为什么要有这样的架构”,“他是什么样子的”,“他是怎么工作的”。

那么阿里程序员是如何去读代码的呢?

2.分布式架构特点及设计理念

首先需要说明的是,分布式系统是一个复杂且宽泛的研究领域,学习一两门在线课程,看一两本书可能都是不能完全覆盖其所有内容的。介于这篇文章是引导初学者入门,所以我个人觉得为初学者介绍一下当前分布式系统领域的全貌,也许比直接推荐论文和课程更有帮助。当初学者对这个领域建立起一个大的 Picture 之后,可以根据自己的兴趣,有选择性的深入不同领域进行进一步的学习。

3.为什么微服务会这么火?

要学习微服务,首先,我们要了解为什么使用微服务。

代码难以理解?

构建和部署耗时长,难以定位问题,开发效率低?

单体只能按整体横向扩展,无法分模块垂直扩展?

一个bug有可能引起整个应用的崩溃?

受技术栈限制,团队成员使用同一框架和语言?

那么如何解决单体的不足呢,通过迁移到微服务架构来解决,我们看一下什么是微服务。

微服务架构:将单体应用拆分为多个高内聚低耦合的小型服务,每个小服务运行在独立进程,由不同的团队开发和维护,服务间采用轻量级通信机制,独立自动部署,可以采用不同的语言及存储。

单体架构整个团队维护开发一个大工程及一个单库,到了微服务架构,用户请求经过API Gateway被路由到下游服务,服务之间以轻量级通信协议进行通信,服务通过注册中心发现彼此,每个服务都有专门的开发维护团队,每个服务对应独立的数据库,服务独立开发,独立部署和上线。

接下来我们总结下微服务的优点。

易于开发与维护

微服务相对小,易于理解

启动时间短,开发效率高

独立部署

一个微服务的修改不需要协调其它服务

伸缩性强

每个服务都可以在横向和纵向上扩展

每个服务都可按硬件资源的需求进行独立扩容

与组织结构相匹配

微服务架构可以更好将架构和组织相匹配

每个团队独立负责某些服务,获得更高的生产力

技术异构性

使用最适合该服务的技术

降低尝试新技术的成本

下面就送上学习架构图吧

工作一到五年的java 开发工程师朋友可以加入我们Java架构交流群:760940986

群内提供 高可用,高并发,spring源码,mybatis源码,JVM,大数据,Netty等多个技术知识的架构视频资料

还有大把大牛在群内交流以及解答面试指导,问题答疑要进来和大牛交流学习提升提升自己吗~~

4.程序员到底要不要学习JVM

总有人问这个东西好像用不上,于是要不要学这样的问题。

然后又总有人担心一直搬砖成天做些重复没提升的东西。

如果你这辈子只甘心做一个平庸的Java码农,那么你完全没有必要去学习JVM相关的知识,学习JVM对于一个Java程序员的好处大概可以概括为下几点:

1.你能够明白为什么Java最早期被称为解释型语言,而后来为什么又被大家叫做解释与编译并存的语言(了解JVM中解释器以及即时编译器就可以回答这个问题);

2.你能够理解动态编译与静态编译的区别,以及动态编译相对于静态编译到底有什么好处(JVM JIT);

3.你能够利用一些工具,jmap, jvisualvm, jstat, jconsole等工具可以辅助你观察Java应用在运行时堆的布局情况,由此你可以通过调整JVM相关参数提高Java应用的性能;

4.可以清楚知道Java程序是如何执行的;

5.可以明白为什么Java等高级语言具有可移植性强的特性。

其实这个问题相当于“为什么C/C++程序员需要学体系结构与编译原理?”

话不多说,附上学习体系图

5.被我们忽略掉的工程化专题

IT产业行业细分化已经不是一天两天的事了。集成技术这件事并不可耻可笑,反而是另一种可贵的能力。并不是像一些人形容的那样,好像批发几个CPU,拿到华强北就能把自己的电脑改装成超级计算机了。

那么,为什么我们常常会忽略掉工程化这件事的价值呢?主要的原因,或许是因为工程化这件事本身就离我们太远。一个产业工程化的普遍性越高,说明这个产业发展的越成熟:产业链细分、分工细化、全球化的研发和生产这些高效的工作方式开始出现。而产业成熟也往往代表着寡头化情况显著。

在IT产业中,寡头化出现代表着创业公司减少——没人再去用声势浩大的发布会讲故事、没人再去宣传自己拿了多少融资。

这一代中国人自小的教育不比欧美的STEAM,而是重学术、轻手艺。我们往往会为工科和产能过剩画上等号。强大的资本和技术门槛为这些产业蒙上了一层神秘的面纱,让普通人很难真正了解到其中技术和工艺的复杂程度,也就更难明白其中的价值。可正是因为中国的工程化能力,才让我们有机会走到AI时代的第一梯队,而不仅仅是靠学术研究能力。

另外一个原因,或许在于我们天生“叛逆心”。超级计算机、手机芯片等等技术门槛较高的产业,其背后往往是大企业和国资科研机构。当评判的对象是他们时,我们似乎更愿意相信狗血的商业故事和阴谋论:比如科研经费都被教授们吃吃喝喝啦;搞超级计算机就是放卫星其实美日根本不care啦;XX企业的技术都是从创业公司买来的除了会赚用户的钱啥技术都没有……

产生这种“叛逆心”的原因太深刻,我们能做到的,只有在这种“惯性思维”出现时先按住自己奔向键盘的手,转表达欲为好奇心,完成自己了解的义务,再去行使自己批判的权利。

附上思维脑图

6.没有高并发经验,想进大公司该怎么办?

假如没有靠谱的公司,接触不到高并发的业务场景怎么办?你永远解决的是小问题,工作10年技术也未必提升多少。

很多程序员也经常找我说,没有经验就没有靠谱的公司收,没有靠谱的公司也就没有经验,我看了无数的书,自己做了无数的实验拼命想找个靠谱公司去深入,但是感觉好难,简直是个死循环

读者群的朋友大家都比较关注高并发,原因很简单,想去BAT这样的大公司,你必须要有高并发的经验。今天普及下高并发的知识,希望大家对高并发有一个正确的认识。

7.学习千遍,不如项目实战成功一次

我们在学习过程中最容易犯的一个错误就是:看的多,动手的少。特别是对一些项目的整体开发,我们接触的机会就更少了。

一次完整的开发,是最好的学习。它能让你对整个开发流程有完整的认识,对知识也会有极大的巩固。更重要的是,你将学会将理论知识用到实际开发中的方法。

所以无论项目大小,一定要动手去进行开发学习。

项目实战相信很多程序员都多少会有的,可是我们这个还要学习什么呢?

那就要看你想不想成为一个架构师了,为什么98%的程序员工作10年,一辈子还只是一个开发者。程序员们都要想一想这个问题,我是不是需要提升了。

我认为,学习项目实战最重要的还是学习项目管理,作为程序员,都应该学点项目管理。

凡事皆为“项目”

项目的两类属性(复杂的逻辑,庞大的信息量)

人脑擅长的是思考,而不是记忆

成为一个“独当一面”的人

独当一面是一个很性感的词。是否拥有它,对应的职场价值,有着天壤之别的。

所有老板都喜欢“独当一面”的员工,因为这是最省心力、最好算账的模式:给你一块资源,给你一个 title,给你一个目标,然后你给我打出一片天地来。

当你能独立对一摊子事情负责,并把它们一一搞定,你会拥有大幅度的职场溢价——相应的,其收入回报,也远非“技术螺丝”可比了。

如果你很进取,你会逐渐地:主导一个小组,一个部门,一个家庭,甚至还是城市……而这所有的一切起点,正是独立完整地做好一个项目:你没有谁可以依靠,你要对其中大大小小的事务负责,你要对最后的结果。

换句话说,“项目管理”是“独当一面”的元能力。在这个过程中,你的意识越发清晰,你的方法论越发成熟,你的信心更加沛,项目越做越大。直到某天,你真的有了掌控一方的封疆大吏。

这就是我们学习“项目实战”的终极意义。

或许作为程序员的你想提升自己,却找不到突破口,公司没人带。又或许你已经工作6年了,却还是很迷茫,很多知识都还是不懂,也没有达到自己期望的一个职位,薪资。在此推荐一个免费公开课的地方,上面所提到的架构师基本知识点都有资料,可以加群:744642380 ,找群主获取上课资格,这是免费的课程,找群主要的时候可以客气一点。

到这里,你可能认为文章已经完了,学完这些就可以去BAT大公司做一个架构师,年薪50W+吗?

不,你错了,这些都知识最基本的知识,想要成为一个架构师必须是一个累积的过程,也是这么多程序员终其一生也只是一个开发,到年龄就会被公司辞退。

这些也是架构师必须要了解到的知识。

编程能力
对工程师而言,编程是最基础的能力,必备技能。其本质是一个翻译能力,将业务需求翻译成机器能懂的语言。

提升编程能力的书籍有很多。精通面向对象和设计模式是高效编程的基础。初级工程师应该多写代码、多看代码。找高手做Code Review,也是提升编程水平的捷径。

编译部署能力
编译并在线上部署运行程序是系统上线的最后一个环节。随着SOA架构的普及以及业务复杂度的增加,大部分系统只是一个完整业务的一个环节,因此,本地编译和运行并不能完全模拟系统在线运行。为了快速验证所编写程序的正确性,编译并在线上部署就成了必要环节。所以编译部署能力是一个必备技能。

让盘根错节的众多子系统运行起来是个不小的挑战。得益于SOA架构的普及以及大量编译、部署工具的发展,编译部署的门槛已经大大降低。基于应用层进行开发的公司,已经很少有“编译工程师”的角色了。但是对于初级工程师而言,编译部署仍然不是一个轻松的事情。

性能优化能力
衡量一个系统成功的一个重要指标是使用量。随着使用量的增加和业务复杂度的增加,大部分系统最终都会碰到性能问题。 性能优化能力是一个综合能力。因为:

影响系统性能的因素众多,包括:数据结构、操作系统、虚拟机、CPU、存储、网络等。为了对系统性能进行调优,架构师需要掌握所有相关的技术。

精通性能优化意味着深刻理解可用性、可靠性、一致性、可维护性、可扩展性等的本质。

性能优化与业务强耦合,最终所采取的手段是往往折衷的结果。所以,性能优化要深谙妥协的艺术。

可以说,性能优化能力是工程师们成长过程中各种技能开始融会贯通的一个标志。这方面可以参考之前的博客文章“常见性能优化策略的总结”。市场上还有很多与性能优化相关的书籍,大家可以参考。多多阅读开源框架中关于性能优化方面的文档和代码也不失为好的提升手段。动手解决线上性能问题也是提升性能优化能力的关键。如果有机会,跟着高手学习,分析性能优化解决方案案例(我们技术博客之前也发表了很多这方面的文章),也是快速提升性能优化能力的手段。

调试能力
程序代码是系统的静态形式,调试的目的是通过查看程序的运行时状态来验证和优化系统。本质上讲,工程师们通过不断调试可以持续强化其通过静态代码去预测运行状态的能力。所以调试能力也是工程师编程能力提升的关键手段。很早之前有个传说:“调试能力有多强,编程能力就有多强。”不过现在很多编辑器的功能很强大,调试能力的门槛已经大大降低。

调试能力是项目能否按时、高质量提交的关键。即使一个稍具复杂度的项目,大部分工程师也无法一次性准确无误的完成。大项目都是通过不断地调试进行优化和纠错的。所以调试能力是不可或缺的能力。

多写程序,解决Bug,多请教高手是提升调试能力的重要手段。

在线运维能力
如果说性能优化能力体现的是架构师的静态思考能力,在线运维能力考验的就是动态反应能力。残酷的现实是,无论程序多么完美,Bug永远存在。与此同时,职位越高、责任越大,很多架构师需要负责非常重要的在线系统。对于线上故障,如果不能提前预防以及快速解决,损失可能不堪设想,所以在线运维能力是优秀架构师的必备技能。

为了对线上故障进行快速处理,标准化的监控、上报、升级,以及基本应对机制当然很重要。通过所观察到的现象,快速定位、缓解以及解决相关症状也相当关键。这要求架构师对故障系统的业务、技术具备通盘解读能力。解决线上故障的架构师就好比一个在参加比赛F1的车手。赛车手必须要了解自身、赛车、对手、同伴、天气、场地等所有因素,快速决策,不断调整。架构师必须要了解所有技术细节、业务细节、处理规范、同伴等众多因素,快速决断,迅速调整。

在线运维本质上是一个强化学习的过程。很多能力都可以通过看书、查资料来完成,但在线运维能力往往需要大量的实践来提升。

业务架构能力
工程师抱怨产品经理的故事屡见不鲜,抱怨最多的主要原因来自于需求的频繁变更。需求变更主要有两个来源:第一个原因是市场改变或战略调整,第二个原因是伪需求。对于第一个原因,无论是工程师还是产品经理,都只能无奈的接受。优秀的架构师应该具备减少第二种原因所导致的需求变更的概率。

伪需求的产生有两个原因:

第一个原因是需求传递变形。从信息论的角度来讲,任何沟通都是一个编码和解码的过程。典型的需求从需求方到产品经理,最终到开发工程师,最少需要经历三次编码和解码过程。而信息的每一次传递都存在一些损失并带来一些噪音,这导致有些时候开发出来的产品完全对不上需求。此外,需求方和产品经理在需求可行性、系统可靠性,开发成本控制方面的把控比较弱,也会导致需求变形。

第二个原因就是需求方完全没有想好自己的需求。

优秀的架构师应该具备辨别真伪需求的能力。应该花时间去了解客户的真实业务场景,具备较强的业务抽象能力,洞悉客户的真实需求。系统的真正实施方是工程师,在明确客户真实需求后,高明的架构师应该具备准确判断项目对可行性、可靠性、可用性等方面的要求,并能具备成本意识。最后,由于需求与在线系统的紧耦合关系,掌握在线系统的各种细节也是成功的业务架构的关键。随着级别的提升,工程师所面对的需求会越来越抽象。承接抽象需求,提供抽象架构是架构师走向卓越的必经之途。

市场上有一些关于如何成为架构师的书,大家可以参考。但是架构能力的提升,实践可能是更重要的方式。业务架构师应该关注客户的痛点而不是PRD文档,应该深入关注真实业务。掌握现存系统的大量技术和业务细节也是业务架构师的必备知识。

项目管理能力
作为工业时代的产物,分工合作融入在互联网项目基因里面。架构师也需要负责几个重大项目才能给自己正名。以架构师角色去管理项目,业务架构能力当然是必备技能。此外,人员管理和成本控制意识也非常重要。

项目管理还意味着要有一个大心脏。重大项目涉及技术攻关、人员变动、需求更改等众多可变因素。面临各种变化,还要在确保目标顺利达成,需要较强的抗压能力。

人员管理需要注意的方面包括:知人善用,优化关系,简化沟通,坚持真理。

知人善用意味着架构师需要了解每个参与者的硬技能和软素质。同时,关注团队成员在项目过程中的表现,按能分配。

优化关系意味着管理团队的情绪,毕竟项目的核心是团队,有士气的团队才能高效达成目标。

简化沟通意味着快速决策,该妥协的时候妥协,权责分明。

坚持真理意味着顶住压力,在原则性问题上绝不退步。

成本控制意味着对项目进行精细化管理,需要遵循如下几个原则:

以终为始、确定里程碑。为了达成目标,所有的计划必须以终为始来制定。将大项目分解成几个小阶段,控制每个阶段的里程碑可以大大降低项目失败的风险。

把控关键路径和关键项目。按照关键路径管理理论(CPM)的要求,架构师需要确定每个子项目的关键路径,确定其最早和最晚启动时间。同时,架构师需要关注那些可能会导致项目整体延期的关键节点,并集中力量攻破。

掌控团队成员的张弛度。大项目持续时间会比较长,也包含不同工种。项目实施是一个不断变化的动态过程,在这个过程中不是整个周期都很紧张,不是所有的工种都一样忙。优秀的架构师必须要具备精细阅读整体项目以及快速反应和实时调整的能力。这不仅仅可以大大降低项目成本,还可以提高产出质量和团队满意度。总体来说,“前紧后松”是项目管理的一个重要原则。

项目管理方面的书籍很多。但是,提高业务架构能力同样重要。积极参与大项目并观察别人管理项目的方式也是非常重要的提升手段。

团队管理能力
不想做CTO的工程师不是一个好的架构师。走向技术管理应该是工程师的一个主流职业规划。团队管理的一个核心能力就是规划能力,这包括项目规划和人员规划。良好的规划需要遵循如下原则:

规划是利益的博弈。良好的规划上面对得起老板,中间对得起自己,下面对得起团队。在三者利益者寻找平衡点,实现多方共赢考验着管理者的智慧和精细拿捏的能力。

任何规划都比没有规划好。没有规划的团队就是没头的苍蝇,不符合所有人的利益。

规划不是本本主义。市场在变,团队在变,规划也不应该一成不变。

客户至上的是项目规划的出发点。

就人员规划而言,规划需要考量团队成员的能力、绩效、成长等多方面的因素。

文章讲到这里已经是终点了,希望可以帮到还在迷茫的朋友,最后祝大家早日年薪50W,成为架构师,欢迎留言和小编讨论。

最后

针对最近很多人都在面试,我这边也整理了相当多的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。

image

上述的面试题答案都整理成文档笔记。 也还整理了一些面试资料&最新2021收集的一些大厂的面试真题(都整理成文档,小部分截图)

资料领取方式:点击这里免费获取

image

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
资料,也有其他大厂的面经。希望可以帮助到大家。

[外链图片转存中…(img-Q5xYCnW1-1615958683259)]

上述的面试题答案都整理成文档笔记。 也还整理了一些面试资料&最新2021收集的一些大厂的面试真题(都整理成文档,小部分截图)

资料领取方式:点击这里免费获取

[外链图片转存中…(img-igEySYFz-1615958683264)]

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1JAVA SE 1.1深入JAVA API 1.1.1Lang包 1.1.1.1String类和StringBuffer类 位于java.lang包中,这个包中的类使用时不用导入 String类一旦初始化就不可以改变,而stringbuffer则可以。它用于封装内容可变的字符串。它可以使用tostring()转换成string字符串。 String x=”a”+4+”c”编译时等效于String x=new StringBuffer().append(“a”).append(4).append(“c”).toString(); 字符串常量是一种特殊的匿名对象,String s1=”hello”;String s2=”hello”;则s1==s2;因为他们指向同一个匿名对象。 如果String s1=new String(“hello”);String s2=new String(“hello”);则s1!=s2; /*逐行读取键盘输入,直到输入为“bye”时,结束程序 注:对于回车换行,在windows下面,有'\r'和'\n'两个,而unix下面只有'\n',但是写程序的时候都要把他区分开*/ public class readline { public static void main(String args[]) { String strInfo=null; int pos=0; byte[] buf=new byte[1024];//定义一个数组,存放换行前的各个字符 int ch=0; //存放读入的字符 system.out.println(“Please input a string:”); while(true) { try { ch=System.in.read(); //该方法每次读入一个字节的内容到ch变量中。 } catch(Exception e) { } switch(ch) { case '\r': //回车时,不进行处理 break; case '\n': //换行时,将数组总的内容放进字符串中 strInfo=new String(buf,0,pos); //该方法将数组中从第0个开始,到第pos个结束存入字符串。 if(strInfo.equals("bye")) //如果该字符串内容为bye,则退出程序。 { return; } else //如果不为bye,则输出,并且竟pos置为0,准备下次存入。 { System.out.println(strInfo); pos=0; break; } default: buf[pos++]=(byte)ch; //如果不是回车,换行,则将读取的数据存入数组中。 } } } } String类的常用成员方法 1、构造方法: String(byte[] byte,int offset,int length);这个在上面已经用到。 2、equalsIgnoreCase:忽略大小写的比较,上例中如果您输入的是BYE,则不会退出,因为大小写不同,但是如果使用这个方法,则会退出。 3、indexOf(int ch);返回字符ch在字符串中首次出现的位置 4、substring(int benginIndex); 5、substring(int beginIndex,int endIndex); 返回字符串的子字符串,4返回从benginindex位置开始到结束的子字符串,5返回beginindex和endindex-1之间的子字符串。 基本数据类型包装类的作用是:将基本的数据类型包装成对象。因为有些方法不可以直接处理基本数据类型,只能处理对象,例如vector的add方法,参数就只能是对象。这时就需要使用他们的包装类将他们包装成对象。 例:在屏幕上打印出一个*组成的矩形,矩形的宽度和高度通过启动程序时传递给main()方法的参数指定。 public class testInteger { public static void main(String[] args) //main()的参数是string类型的数组,用来做为长,宽时,要转换成整型。 { int w=new Integer(args[0]).intValue(); int h=Integer.parseInt(args[1]); //int h=Integer.valueOf(args[1]).intValue(); //以上为三种将字符串转换成整形的方法。 for(int i=0;i<h;i++) { StringBuffer sb=new StringBuffer(); //使用stringbuffer,是因为它是可追加的。 for(int j=0;j<w;j++) { sb.append('*'); } System.out.println(sb.toString()); //在打印之前,要将stringbuffer转化为string类型。 } } } 比较下面两段代码的执行效率: (1)String sb=new String(); For(int j=0;j<w;j++) { Sb=sb+’*’; } (2) StringBuffer sb=new StringBuffer(); For(int j=0;j<w;j++) { Sb.append(‘*’); } (1)和(2)在运行结果上相同,但效率相差很多。 (1)在每一次循环中,都要先将string类型转换为stringbuffer类型,然后将‘*’追加进去,然后再调用tostring()方法,转换为string类型,效率很低。 (2)在没次循环中,都只是调用原来的那个stringbuffer对象,没有创建新的对象,所以效率比较高。 1.1.1.2System类与Runtime类 由于java不支持全局函数和全局变量,所以java设计者将一些与系统相关的重要函数和变量放在system类中。 我们不能直接创建runtime的实例,只能通过runtime.getruntime()静态方法来获得。 编程实例:在java程序中启动一个windows记事本程序的运行实例,并在该运行实例中打开该运行程序的源文件,启动的记事本程序5秒后关闭。 public class Property { public static void main(String[] args) { Process p=null; //java虚拟机启动的进程。 try { p=Runtime.getRuntime().exec("notepad.exe Property.java"); //启动记事本并且打开源文件。 Thread.sleep(5000); //持续5秒 p.destroy(); //关闭该进程 } catch(Exception ex) { ex.printStackTrace(); } } } 1.1.1.3Java语言中两种异常的差别 Java提供了两类主要的异常:runtime exception和checked exception。所有的checked exception是从java.lang.Exception类衍生出来的,而runtime exception则是从java.lang.RuntimeException或java.lang.Error类衍生出来的。    它们的不同之处表现在两方面:机制上和逻辑上。    一、机制上    它们在机制上的不同表现在两点:1.如何定义方法;2. 如何处理抛出的异常。请看下面CheckedException的定义:    public class CheckedException extends Exception    {    public CheckedException() {}    public CheckedException( String message )    {    super( message );    }    }    以及一个使用exception的例子:    public class ExceptionalClass    {    public void method1()    throws CheckedException    {     // ... throw new CheckedException( “...出错了“ );    }    public void method2( String arg )    {     if( arg == null )     {      throw new NullPointerException( “method2的参数arg是null!” );     }    }    public void method3() throws CheckedException    {     method1();    }    }    你可能已经注意到了,两个方法method1()和method2()都会抛出exception,可是只有method1()做了声明。另外,method3()本身并不会抛出exception,可是它却声明会抛出CheckedException。在向你解释之前,让我们先来看看这个类的main()方法:    public static void main( String[] args )    {    ExceptionalClass example = new ExceptionalClass();    try    {    example.method1();    example.method3();    }    catch( CheckedException ex ) { } example.method2( null );    }    在main()方法中,如果要调用method1(),你必须把这个调用放在try/catch程序块当中,因为它会抛出Checked exception。    相比之下,当你调用method2()时,则不需要把它放在try/catch程序块当中,因为它会抛出的exception不是checked exception,而是runtime exception。会抛出runtime exception的方法在定义时不必声明它会抛出exception。    现在,让我们再来看看method3()。它调用了method1()却没有把这个调用放在try/catch程序块当中。它是通过声明它会抛出method1()会抛出的exception来避免这样做的。它没有捕获这个exception,而是把它传递下去。实际上main()方法也可以这样做,通过声明它会抛出Checked exception来避免使用try/catch程序块(当然我们反对这种做法)。    小结一下:    * Runtime exceptions:    在定义方法时不需要声明会抛出runtime exception;    在调用这个方法时不需要捕获这个runtime exception;    runtime exception是从java.lang.RuntimeException或java.lang.Error类衍生出来的。    * Checked exceptions:    定义方法时必须声明所有可能会抛出的checked exception;    在调用这个方法时,必须捕获它的checked exception,不然就得把它的exception传递下去;    checked exception是从java.lang.Exception类衍生出来的。    二、逻辑上    从逻辑的角度来说,checked exceptions和runtime exception是有不同的使用目的的。checked exception用来指示一种调用方能够直接处理的异常情况。而runtime exception则用来指示一种调用方本身无法处理或恢复的程序错误。    checked exception迫使你捕获它并处理这种异常情况。以java.net.URL类的构建器(constructor)为例,它的每一个构建器都会抛出MalformedURLException。MalformedURLException就是一种checked exception。设想一下,你有一个简单的程序,用来提示用户输入一个URL,然后通过这个URL去下载一个网页。如果用户输入的URL有错误,构建器就会抛出一个exception。既然这个exception是checked exception,你的程序就可以捕获它并正确处理:比如说提示用户重新输入。 

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值