JAVA基础——异常详解

JAVA基础——异常详解

阅读目录

JAVA异常与异常处理详解

回到顶部

一、异常简介

什么是异常?

异常就是有异于常态,和正常情况不一样,有错误出错。在java中,阻止当前方法或作用域的情况,称之为异常。

java中异常的体系是怎么样的呢?

1.Java中的所有不正常类都继承于Throwable类。Throwable主要包括两个大类,一个是Error类,另一个是Exception类;

    

 2.其中Error类中包括虚拟机错误和线程死锁,一旦Error出现了,程序就彻底的挂了,被称为程序终结者;

   

3.Exception类,也就是通常所说的“异常”。主要指编码、环境、用户操作输入出现问题,Exception主要包括两大类,非检查异常(RuntimeException)和检查异常(其他的一些异常)

    

4.RuntimeException异常主要包括以下四种异常(其实还有很多其他异常,这里不一一列出):空指针异常、数组下标越界异常、类型转换异常、算术异常。RuntimeException异常会由java虚拟机自动抛出并自动捕获(就算我们没写异常捕获语句运行时也会抛出错误!!),此类异常的出现绝大数情况是代码本身有问题应该从逻辑上去解决并改进代码。

  

5.检查异常,引起该异常的原因多种多样,比如说文件不存在、或者是连接错误等等。跟它的“兄弟”RuntimeException运行异常不同,该异常我们必须手动在代码里添加捕获语句来处理该异常,这也是我们学习java异常语句中主要处理的异常对象。

  

回到顶部

二、try-catch-finally语句

(1)try块:负责捕获异常,一旦try中发现异常,程序的控制权将被移交给catch块中的异常处理程序。

  【try语句块不可以独立存在,必须与 catch 或者 finally 块同存】

(2)catch块:如何处理?比如发出警告:提示、检查配置、网络连接,记录错误等。执行完catch块之后程序跳出catch块,继续执行后面的代码。

    【编写catch块的注意事项:多个catch块处理的异常类,要按照先catch子类后catch父类的处理方式,因为会【就近处理】异常(由上自下)。

(3)finally:最终执行的代码,用于关闭和释放资源。

=======================================================================

语法格式如下:

try{
//一些会抛出的异常
}catch(Exception e){
//第一个catch
//处理该异常的代码块
}catch(Exception e){
//第二个catch,可以有多个catch
//处理该异常的代码块
}finally{
//最终要执行的代码
} 

当异常出现时,程序将终止执行,交由异常处理程序(抛出提醒或记录日志等),异常代码块外代码正常执行。 try会抛出很多种类型的异常,由多个catch块捕获多钟错误

多重异常处理代码块顺序问题:先子类再父类(顺序不对编译器会提醒错误),finally语句块处理最终将要执行的代码。

=======================================================================

接下来,我们用实例来巩固try-catch语句吧~

先看例子:

 1 package com.hysum.test;
 2 
 3 public class TryCatchTest {
 4     /**
 5      * divider:除数
 6      * result:结果
 7      * try-catch捕获while循环
 8      * 每次循环,divider减一,result=result+100/divider
 9      * 如果:捕获异常,打印输出“异常抛出了”,返回-1
10      * 否则:返回result
11      * @return
12      */
13     public int test1(){
14         int divider=10;
15         int result=100;
16         try{
17             while(divider>-1){
18                 divider--;
19                 result=result+100/divider;
20             }
21             return result;
22         }catch(Exception e){
23             e.printStackTrace();
24             System.out.println("异常抛出了!!");
25             return -1;
26         }
27     }
28     public static void main(String[] args) {
29         // TODO Auto-generated method stub
30         TryCatchTest t1=new TryCatchTest();
31         System.out.println("test1方法执行完毕!result的值为:"+t1.test1());
32     }
33     
34 }

运行结果:

结果分析:结果中的红色字抛出的异常信息是由e.printStackTrace()来输出的,它说明了这里我们抛出的异常类型是算数异常,后面还跟着原因:by zero(由0造成的算数异常),下面两行at表明了造成此异常的代码具体位置。

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

在上面例子中再加上一个test2()方法来测试finally语句的执行状况:

 1     /**
 2      * divider:除数
 3      * result:结果
 4      * try-catch捕获while循环
 5      * 每次循环,divider减一,result=result+100/divider
 6      * 如果:捕获异常,打印输出“异常抛出了”,返回result=999
 7      * 否则:返回result
 8      * finally:打印输出“这是finally,哈哈哈!!”同时打印输出result
 9      * @return
10      */
11     public int test2(){
12         int divider=10;
13         int result=100;
14         try{
15             while(divider>-1){
16                 divider--;
17                 result=result+100/divider;
18             }
19             return result;
20         }catch(Exception e){
21             e.printStackTrace();
22             System.out.println("异常抛出了!!");
23             return result=999;
24         }finally{
25             System.out.println("这是finally,哈哈哈!!");
26             System.out.println("result的值为:"+result);
27         }
28         
29     }
30     
31     
32     
33     public static void main(String[] args) {
34         // TODO Auto-generated method stub
35         TryCatchTest t1=new TryCatchTest();
36         //System.out.println("test1方法执行完毕!result的值为:"+t1.test1());
37         t1.test2();
38         System.out.println("test2方法执行完毕!");
39     }

运行结果:

结果分析:我们可以从结果看出,finally语句块是在try块和catch块语句执行之后最后执行的。finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,仍然是之前保存的值),所以函数返回值是在finally执行前确定的;

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

这里有个有趣的问题,如果把上述中的test2方法中的finally语句块中加上return,编译器就会提示警告:finally block does not complete normally 

 1 public int test2(){
 2         int divider=10;
 3         int result=100;
 4         try{
 5             while(divider>-1){
 6                 divider--;
 7                 result=result+100/divider;
 8             }
 9             return result;
10         }catch(Exception e){
11             e.printStackTrace();
12             System.out.println("异常抛出了!!");
13             return result=999;
14         }finally{
15             System.out.println("这是finally,哈哈哈!!");
16             System.out.println("result的值为:"+result);
17             return result;//编译器警告
18         }
19         
20     }

分析问题: finally块中的return语句可能会覆盖try块、catch块中的return语句;如果finally块中包含了return语句,即使前面的catch块重新抛出了异常,则调用该方法的语句也不会获得catch块重新抛出的异常,而是会得到finally块的返回值,并且不会捕获异常。

解决问题:面对上述情况,其实更合理的做法是,既不在try block内部中使用return语句,也不在finally内部使用 return语句,而应该在 finally 语句之后使用return来表示函数的结束和返回。如:

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

 总结:

  1、不管有木有出现异常或者try和catch中有返回值return,finally块中代码都会执行;

  2、finally中最好不要包含return,否则程序会提前退出,返回会覆盖try或catch中保存的返回值。

  3.  e.printStackTrace()可以输出异常信息。

  4.  return值为-1为抛出异常的习惯写法。

  5.  如果方法中try,catch,finally中没有返回语句,则会调用这三个语句块之外的return结果。

  6.  finally 在try中的return之后 在返回主调函数之前执行。

回到顶部

三、throw和throws关键字

java中的异常抛出通常使用throw和throws关键字来实现。

throw ----将产生的异常抛出,是抛出异常的一个动作

一般会用于程序出现某种逻辑时程序员主动抛出某种特定类型的异常。如:
  语法:throw (异常对象),如:

1 public static void main(String[] args) { 
2     String s = "abc"; 
3     if(s.equals("abc")) { 
4       throw new NumberFormatException(); 
5     } else { 
6       System.out.println(s); 
7     } 
8     //function(); 
9 } 

运行结果:

Exception in thread "main" java.lang.NumberFormatException
at test.ExceptionTest.main(ExceptionTest.java:67)

throws----声明将要抛出何种类型的异常(声明)。

语法格式:

1 public void 方法名(参数列表)
2    throws 异常列表{
3 //调用会抛出异常的方法或者:
4 throw new Exception();
5 }

当某个方法可能会抛出某种异常时用于throws 声明可能抛出的异常,然后交给上层调用它的方法程序处理。如:

 1 public static void function() throws NumberFormatException{ 
 2     String s = "abc"; 
 3     System.out.println(Double.parseDouble(s)); 
 4   } 
 5     
 6   public static void main(String[] args) { 
 7     try { 
 8       function(); 
 9     } catch (NumberFormatException e) { 
10       System.err.println("非数据类型不能转换。"); 
11       //e.printStackTrace(); 
12     } 
13 } 

throw与throws的比较
1、throws出现在方法函数头;而throw出现在函数体。
2、throws表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某种异常对象。
3、两者都是消极处理异常的方式(这里的消极并不是说这种方式不好),只是抛出或者可能抛出异常,但是不会由函数去处理异常,真正的处理异常由函数的上层调用处理。

来看个例子:

throws e1,e2,e3只是告诉程序这个方法可能会抛出这些异常,方法的调用者可能要处理这些异常,而这些异常e1,e2,e3可能是该函数体产生的。
throw则是明确了这个地方要抛出这个异常。如:

 1 void doA(int a) throws (Exception1,Exception2,Exception3){
 2       try{
 3          ......
 4  
 5       }catch(Exception1 e){
 6        throw e;
 7       }catch(Exception2 e){
 8        System.out.println("出错了!");
 9       }
10       if(a!=b)
11        throw new Exception3("自定义异常");
12 }

分析:
1.代码块中可能会产生3个异常,(Exception1,Exception2,Exception3)。
2.如果产生Exception1异常,则捕获之后再抛出,由该方法的调用者去处理。
3.如果产生Exception2异常,则该方法自己处理了(即System.out.println("出错了!");)。所以该方法就不会再向外抛出Exception2异常了,void doA() throws Exception1,Exception3 里面的Exception2也就不用写了。因为已经用try-catch语句捕获并处理了。
4.Exception3异常是该方法的某段逻辑出错,程序员自己做了处理,在该段逻辑错误的情况下抛出异常Exception3,则该方法的调用者也要处理此异常。这里用到了自定义异常,该异常下面会由解释。

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

使用throw和throws关键字需要注意以下几点:

1.throws的异常列表可以是抛出一条异常,也可以是抛出多条异常,每个类型的异常中间用逗号隔开

2.方法体中调用会抛出异常的方法或者是先抛出一个异常:用throw new Exception() throw写在方法体里,表示“抛出异常”这个动作。

3.如果某个方法调用了抛出异常的方法,那么必须添加try catch语句去尝试捕获这种异常, 或者添加声明,将异常抛出给更上一层的调用者进行处理

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

自定义异常

为什么要使用自定义异常,有什么好处

1.我们在工作的时候,项目是分模块或者分功能开发的 ,基本不会你一个人开发一整个项目,使用自定义异常类就统一了对外异常展示的方式

2.有时候我们遇到某些校验或者问题时,需要直接结束掉当前的请求,这时便可以通过抛出自定义异常来结束,如果你项目中使用了SpringMVC比较新的版本的话有控制器增强,可以通过@ControllerAdvice注解写一个控制器增强类来拦截自定义的异常并响应给前端相应的信息。

3.自定义异常可以在我们项目中某些特殊的业务逻辑时抛出异常,比如"中性".equals(sex),性别等于中性时我们要抛出异常,而Java是不会有这种异常的。系统中有些错误是符合Java语法的,但不符合我们项目的业务逻辑。

4.使用自定义异常继承相关的异常来抛出处理后的异常信息可以隐藏底层的异常,这样更安全,异常信息也更加的直观。自定义异常可以抛出我们自己想要抛出的信息,可以通过抛出的信息区分异常发生的位置,根据异常名我们就可以知道哪里有异常,根据异常提示信息进行程序修改。比如空指针异常NullPointException,我们可以抛出信息为“xxx为空”定位异常位置,而不用输出堆栈信息。

说完了为什么要使用自定义异常,有什么好处,我们再来看看自定义异常的毛病

毋庸置疑,我们不可能期待JVM(Java虚拟机)自动抛出一个自定义异常,也不能够期待JVM会自动处理一个自定义异常。发现异常、抛出异常以及处理异常的工作必须靠编程人员在代码中利用异常处理机制自己完成。这样就相应的增加了一些开发成本和工作量,所以项目没必要的话,也不一定非得要用上自定义异常,要能够自己去权衡。

最后,我们来看看怎么使用自定义异常:

在 Java 中你可以自定义异常。编写自己的异常类时需要记住下面的几点。

  • 所有异常都必须是 Throwable 的子类。
  • 如果希望写一个检查性异常类,则需要继承 Exception 类。
  • 如果你想写一个运行时异常类,那么需要继承 RuntimeException 类。

可以像下面这样定义自己的异常类:

class MyException extends Exception{ }

我们来看一个实例:

 1 package com.hysum.test;
 2 
 3 public class MyException extends Exception {
 4      /**
 5      * 错误编码
 6      */
 7     private String errorCode;
 8 
 9    
10     public MyException(){}
11     
12     /**
13      * 构造一个基本异常.
14      *
15      * @param message
16      *        信息描述
17      */
18     public MyException(String message)
19     {
20         super(message);
21     }
22 
23    
24 
25     public String getErrorCode() {
26         return errorCode;
27     }
28 
29     public void setErrorCode(String errorCode) {
30         this.errorCode = errorCode;
31     }
32 
33     
34 }

使用自定义异常抛出异常信息:

 1 package com.hysum.test;
 2 
 3 public class Main {
 4 
 5     public static void main(String[] args) {
 6         // TODO Auto-generated method stub
 7         String[] sexs = {"男性","女性","中性"};
 8                   for(int i = 0; i < sexs.length; i++){
 9                       if("中性".equals(sexs[i])){
10                           try {
11                             throw new MyException("不存在中性的人!");
12                         } catch (MyException e) {
13                             // TODO Auto-generated catch block
14                             e.printStackTrace();
15                         }
16                      }else{
17                          System.out.println(sexs[i]);
18                      }
19                 } 
20     }
21 
22 }

运行结果:

 就是这么简单,可以根据实际业务需求去抛出相应的自定义异常。

回到顶部

四、java中的异常链

异常需要封装,但是仅仅封装还是不够的,还需要传递异常

异常链是一种面向对象编程技术,指将捕获的异常包装进一个新的异常中并重新抛出的异常处理方式。原异常被保存为新异常的一个属性(比如cause)。这样做的意义是一个方法应该抛出定义在相同的抽象层次上的异常,但不会丢弃更低层次的信息。

我可以这样理解异常链:

把捕获的异常包装成新的异常,在新异常里添加原始的异常,并将新异常抛出,它们就像是链式反应一样,一个导致(cause)另一个。这样在最后的顶层抛出的异常信息就包括了最底层的异常信息。

》场景

比如我们的JEE项目一般都又三层:持久层、逻辑层、展现层,持久层负责与数据库交互,逻辑层负责业务逻辑的实现,展现层负责UI数据的处理。

有这样一个模块:用户第一次访问的时候,需要持久层从user.xml中读取数据,如果该文件不存在则提示用户创建之,那问题就来了:如果我们直接把持久层的异常FileNotFoundException抛弃掉,逻辑层根本无从得知发生任何事情,也就不能为展现层提供一个友好的处理结果,最终倒霉的就是展现层:没有办法提供异常信息,只能告诉用户“出错了,我也不知道出了什么错了”—毫无友好性而言。

正确的做法是先封装,然后传递,过程如下:

 1.把FileNotFoundException封装为MyException。

    2.抛出到逻辑层,逻辑层根据异常代码(或者自定义的异常类型)确定后续处理逻辑,然后抛出到展现层。

    3.展现层自行确定展现什么,如果管理员则可以展现低层级的异常,如果是普通用户则展示封装后的异常。

》示例

 1 package com.hysum.test;
 2 
 3 public class Main {
 4     public void test1() throws RuntimeException{
 5         String[] sexs = {"男性","女性","中性"};
 6         for(int i = 0; i < sexs.length; i++){
 7             if("中性".equals(sexs[i])){
 8                 try {
 9                     throw new MyException("不存在中性的人!");
10                 } catch (MyException e) {
11                     // TODO Auto-generated catch block
12                     e.printStackTrace();
13                     RuntimeException rte=new RuntimeException(e);//包装成RuntimeException异常
14                     //rte.initCause(e);
15                     throw rte;//抛出包装后的新的异常
16                 }
17            }else{
18                System.out.println(sexs[i]);
19            }
20       } 
21     }
22     public static void main(String[] args) {
23         // TODO Auto-generated method stub
24         Main m =new Main();
25         
26         try{
27         m.test1();
28         }catch (Exception e){
29             e.printStackTrace();
30             e.getCause();//获得原始异常
31         }
32         
33     }
34 
35 }

运行结果:

结果分析:我们可以看到控制台先是输出了原始异常,这是由e.getCause()输出的;然后输出了e.printStackTrace(),在这里可以看到Caused by:原始异常和e.getCause()输出的一致。这样就是形成一个异常链。initCause()的作用是包装原始的异常,当想要知道底层发生了什么异常的时候调用getCause()就能获得原始异常。 

》建议

异常需要封装和传递,我们在进行系统开发的时候,不要“吞噬”异常,也不要“赤裸裸”的抛出异常,封装后在抛出,或者通过异常链传递,可以达到系统更健壮、友好的目的。

回到顶部

五、结束语

java的异常处理的知识点杂而且理解起来也有点困难,我在这里给大家总结了以下几点使用java异常处理的时候,良好的编码习惯:

1、处理运行时异常时,采用逻辑去合理规避同时辅助try-catch处理

2、在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常

3、对于不确定的代码,也可以加上try-catch,处理潜在的异常

4、尽量去处理异常,切记只是简单的调用printStackTrace()去打印

5、具体如何处理异常,要根据不同的业务需求和异常类型去决定

6、尽量添加finally语句块去释放占用的资源

  • 24
    点赞
  • 111
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
基本信息 作者: 臧萌 出版社:清华大学出版社 ISBN:9787302217831 上架时间:2010-3-30 出版日期:2010 年3月 开本:16开 其他详细信息查看:http://www.china-pub.com/196571 编辑推荐 Java编程老鸟潜心写作,奉献高效率的Java学习心得 完全站在没有编程经验读者的角度,手把手教会读者学习Java 配16小时多媒体教学视频,高效、直观 一一击破Java入门可能会遇到的难点和疑惑 抽丝剥茧,层层推进,让知识环环相扣,降低了学习的难度 通过大量的比喻、类比、对比和图示等多种讲解方式,学习效果好 对Java语言的每个语法都提供了一个或多个例程讲解 大量使用流程图表示程序的执行过程,使用结构图表示程序的内部状态 每章最后都给出了典型的练习题,让读者及时练习,巩固提高,并提供了参考答案 目录 第1篇 Java语言基本语法 第1章 让自己的第一个Java程序跑起来 2 教学视频:19分钟 1.1 想要用Java改变这个世界吗? 2 1.1.1 Java有什么优势? 2 1.1.2 Java在哪儿? 3 1.2 准备好开始Java之旅 3 1.2.1 下载JDK 4 1.2.2 安装JDK 5 1.2.3 配置环境变量 6 1.2.4 测试环境是否安装成功 8 1.2.5 如果失败了怎么办? 9 1.3 让自己的第一个程序运行起来 10 1.3.1 编写自己的Hello World源程序 10 1.3.2 编译自己的HelloWorld程序 11 1.3.3 让代码运行起来 13 1.4 初探Hello World 14 1.4.1 类(Class):Java世界中一类物体 14 1.4.2 方法(Method):物体的功能 15 1.4.3 main()方法:所有Java程序执行的起点 15 .1.5 名词解释 16 1.5.1 JDK和Java平台 16 1.5.2 Java编译器(Java Compiler) 17 1.5.3 Java类库(Java Class Libraries) 17 1.5.4 Java虚拟机(Java Virtual Machine) 17 1.5.5 HelloWorld的整个流程 17 1.6 小结:我们学会了编译和运行一个Java程序! 18 1.7 习题 19 第2章 搭建自己的集成开发环境 20 教学视频:31分钟 2.1 安装集成开发环境 20 2.1.1 集成开发环境有哪些 20 2.1.2 安装Eclipse 21 2.2 Eclipse界面介绍 23 2.2.1 启动Eclipse 23 2.2.2 Eclipse的Perspective 24 2.2.3 Eclipse的菜单 25 2.2.4 Eclipse的工具条 25 2.2.5 Eclipse辅助视图区 25 2.2.6 Eclipse中Package Explorer 26 2.2.7 Eclipse中的源代码编辑器 26 2.2.8 Eclipse的设置窗口 26 2.2.9 Eclipse中的其他视图 27 2.3 如何使用Eclipse 28 2.3.1 在Eclipse中创建自己的第一个项目 28 2.3.2 在Eclipse中编写HelloWorld程序 29 2.3.3 通过Eclipse运行Hello World 31 2.4 小结:Eclipse——功能很强大 32 2.5 习题 32 第3章 Java中的基本数据类型和运算符 33 教学视频:1小时5分钟 3.1 Java中的基本数据类型 33 3.1.1 基本数据类型——编程语言中的数据原子 33 3.1.2 Java中的基本上数据类型介绍 34 3.1.3 基本数据类型值域 34 3.2 Java运算符 36 3.2.1 变量的概念 36 3.2.2 插曲:Java中的语句 37 3.2.3 创建一个变量和变量名的规范 37 3.2.4 Java中的基本运算符和表达式 39 3.2.5 Java中的布尔运算符 43 3.3 基本数据类型运算的难点 47 3.3.1 强制类型转换——小数哪里去了 48 3.3.2 类型的转换在运算中悄悄进行 50 3.3.3 强制类型转换最优先 52 3.3.4 等号其实不简单 52 3.3.5 小心使用浮点数进行比较 53 3.3.6 boolean和char 55 3.3.7 不要使用还没有创建出来的变量 57 3.3.8 String——char串起的项链 58 3.3.9 转义符——看不见写得出 61 3.4 小结:基本数据类型—— Java中一切数据和运算的基础 63 3.5 习题 65 第4章 Java中的程序执行流程 67 教学视频:1小时57分钟 4.1 顺序执行 67 4.2 使用if-else让程序懂得判断 68 4.2.1 if语句 68 4.2.2 if语句的嵌套 71 4.2.3 if-else语句 73 4.2.4 if-else语句嵌套 75 4.3 使用while进行循环 76 4.3.1 使用while语句 76 4.3.2 使用do-while语句 79 4.4 使用for进行循环 80 4.4.1 自增和自减操作 80 4.4.2 for语句 82 4.4.3 for语句省略形式 84 4.5 语句中不能不说的事 84 4.5.1 小心复杂语句中创建的变量 85 4.5.2 别让循环次数给弄懵了 86 4.5.3 循环的嵌套 87 4.6 continue关键字与break关键字 88 4.6.1 continue关键字 88 4.6.2 break关键字 89 4.7 使用switch进行跳转 90 4.8 大例子 94 4.8.1 从控制台读取数据 94 4.8.2 结账程序中的循环 96 4.9 小结:Java不是一个直肠子 98 4.10 习题 99 第5章 数组 100 教学视频:35分钟 5.1 什么是数组 100 5.1.1 假设:如果需要逐个定义变量 100 5.1.2 数组初探 101 5.1.3 数组——物以类聚 104 5.1.4 数组元素的值内有乾坤 105 5.1.5 创建数组的简洁语法 106 5.2 数组的“名”与“实” 107 5.2.1 “名”与“实”分离的数组 107 5.2.2 一“实”多“名”的数组 109 5.2.3 一“实”多“名”带来的困惑 111 5.3 多维数组 114 5.3.1 什么是多维数组 114 5.3.2 多维数组的实质 115 5.4 数组大练兵 123 5.4.1 轻松查询全班成绩 123 5.4.2 轻松查询全校成绩不在话下 124 5.4.3 杨辉三角 125 5.5 小结:方便快速的数组 129 5.6 习题 129 第2篇 Java语言高级语法 第6章 Java的类(Class)和对象(Object) 132 教学视频:59分钟 6.1 驾驶汽车向类(Class)的世界进发 132 6.1.1 汽车带来的问题 132 6.1.1 类的组成 134 6.1.3 使用自定义的Car类 136 6.1.4 类和对象 139 6.1.5 源文件的存放 141 6.1.5 理解引用 143 6.1.7 null关键字 145 6.2 巧妙使用类中的属性 147 6.2.1 在类中给每个变量一个初始值 147 6.2.2 定义自己的引用 147 6.2.3 使用点操作符的技巧 148 6.2.4 类的数组 149 6.3 小结:Java其实是个类和对象的世界 152 6.4 习题 153 第7章 Java中的方法——给汽车丰富多彩的功能 154 教学视频:2小时55分钟 7.1 方法:让汽车动开动 154 7.1.1 引出问题:开动汽车 154 7.1.2 那么,方法到底是什么呢? 155 7.1.3 方法调用过程初探 156 7.2 Java普通方法的组成部分 157 7.2.1 访问控制符:public 158 7.2.2 返回值和关键字void 158 7.2.3 方法名(Method Name) 159 7.2.4 参数列表(Parameter List) 159 7.2.5 方法体(Method Body) 160 7.2.6 方法串串烧 160 7.3 方法的参数:让汽车加速 161 7.3.1 方法的参数:让汽车可以加速 161 7.3.2 带参数的方法有何不同? 162 7.3.3 让方法有多个参数 163 7.4 返回值:汽车超速了吗? 164 7.4.1 写一个有返回值的方法 164 7.4.2 调用有返回值的方法 165 7.4.3 发生了什么?如何使用方法的返回值? 166 7.4.4 使用return结束方法 166 7.5 方法重载(overload):给汽车加速添个限制 168 7.5.1 什么是方法的签名 168 7.5.2 什么是重载?为什么要重载? 168 7.5.3 给汽车加个重载的方法 169 7.5.4 测试一下 169 7.5.5 重载容易引发误解的两个地方——返回类型和形参名 170 7.5.6 重载中的最难点——参数匹配原则 171 7.6 使用类的实例作为方法参数 172 7.6.1 超车方法:使用类实例做参数 172 7.6.2 调用这个方法 173 7.6.3 发生了什么 174 7.7 加餐:局部变量和实例变量 175 7.7.1 什么是局部变量(Local Variable) 175 7.7.2 什么是实例变量(Instance Variable) 177 7.8 this关键字:指向对象自己的引用 177 7.8.1 发现问题:当实例变量和局部变量重名 177 7.8.2 经常深藏不露的this关键字 178 7.8.3 在方法中调用方法 179 7.9 构造方法(Constructor) 181 7.9.1 构造(Constructor)方法初探 181 7.9.2 如何使用构造方法 182 7.9.3 留个无参数的构造方法——给重要属性赋初始值 183 7.9.4 在构造方法中调用构造方法 184 7.10 方法大汇总 185 7.10.1 本例中用到的类 186 7.10.2 使用例程将本章的知识穿起来 189 7.11 小结:多方位理解Java方法 191 7.12 习题 192 第8章 Java中的包(Package)命名习惯和注释 193 教学视频:43分钟 8.1 Java中的包(Package) 193 8.1.1 Java中的包 193 8.1.2 在Eclipse中使用包 194 8.1.3 天上掉下个package 197 8.1.4 包带来了什么? 197 8.2 import语句:化繁为简 200 8.2.1 import语句 200 8.2.2 一网打尽包中所有类 201 8.2.3 import语句带来的小问题 202 8.2.4 默认引入的包 204 8.3 命名习惯大回顾 204 8.4 Java中的注释 205 8.4.1 使用双斜杠的单行注释 205 8.4.2 多行注释 206 8.4.3 Javadoc注释 206 8.5 小结:包让Java的类更清晰优雅 208 8.6 习题 209 第9章 再看数组、字符串和main()方法 210 教学视频:29分钟 9.1 数组也是类 210 9.1.1 得到数组的长度 210 9.1.2 加餐:不可改变的final变量 211 9.1.3 多维数组的长度 212 9.1.4 一维数组的clone()方法 212 9.1.5 当数组类型不再是基本数据类型 214 9.1.6 多维数组的clone()方法 217 9.2 老朋友String类 220 9.2.1 遍历String中的字符 220 9.2.2 获取字符串中的一部分 222 9.2.3 判断两个字符串是否相等 223 9.2.4 判断字符串的开头和结尾 225 9.2.5 分割字符串 225 9.2.6 在字符串中查找子字符串或字符 226 9.2.7 替换字符串中的内容 226 9.2.8 String对象——磐石刻字 227 9.3 String类的最佳拍档——StringBuffer类 227 9.3.1 StringBuffer:专业操纵字符 228 9.3.2 String和StringBuffer一个都不能少 229 9.4 最熟悉的陌生人:main()方法 229 9.4.1 main()方法的参数 229 9.4.2 static关键字 232 9.4.3 当方法遇到static关键字 233 9.5 小结:学会使用类中的方法 235 9.6 习题 236 第10章 继承和多态 237 教学视频:1小时55分钟 10.1 继承——最优的解决方案 237 10.1.1 饭前水果:实例变量的访问控制符 237 10.1.2 一切还是从汽车开始 238 10.1.3 一类车,一个类 241 10.1.4 分开也有麻烦 244 10.1.5 使用继承——问题迎刃而解 245 10.1.6 使用Bus类 248 10.1.7 Java中的单继承 248 10.1.8 Java中的类图 249 10.1.9 万类之祖——Object类 250 10.2 子类对象?父类对象? 251 10.2.1 父随子行 251 10.2.2 当构造方法遇到继承 254 10.2.3 记得给类一个无参数的构造方法 255 10.2.4 调用父类中的构造方法 256 10.2.5 对象也会“变脸” 258 10.2.6 遵守语法,正确“变脸” 262 10.3 覆盖——与继承如影随形 264 10.3.1 当方法不再通用 264 10.3.2 覆盖——让众口不再难调 265 10.3.3 覆盖——到底调用了哪个方法 270 10.3.4 覆盖的语法不简单 272 10.3.5 更复杂的使用覆盖的情况 274 10.3.6 覆盖——不得不打开的潘多拉魔盒 276 10.3.7 使用super调用父类中的方法和属性 278 10.4 多态(Polymorphism)以及其他 279 10.4.1 多态——运行方知结果 280 10.4.2 重载也不简单 280 10.4.3 使用多态构建车队 283 10.5 在多态的环境中拨开迷雾 284 10.5.1 神秘的Class类 284 10.5.2 覆盖不再神秘 285 10.5.3 instanceof运算符——让对象告诉你它的类是谁 286 10.6 小结:继承和多态让世界丰富多彩 287 10.7 习题 290 第11章 修饰符(Qualifier) 291 教学视频:26分钟 11.1 插曲:类的组成部分的名字 291 11.2 类中的修饰符 292 11.2.1 无修饰符类 292 11.2.2 类的可见性 293 11.2.3 final——让类不可被继承 295 11.2.4 理解final关键字 296 11.2.5 总结:类的修饰符 297 11.3 方法的修饰符 297 11.3.1 方法的访问控制符 298 11.3.2 public:没有限制的修饰符 299 11.3.3 protected:仅对子类和同包的类可见 300 11.3.4 默认控制符:仅在本包中可见 301 11.3.5 private:仅对本类可见 303 11.3.6 理解4个访问控制符 304 11.3.7 访问控制符可见性汇总 306 11.3.8 访问控制符带来的覆盖问题 306 11.3.9 final:不允许方法被覆盖 310 11.3.10 重温静态方法 311 11.3.11 静态方法——类范围里的概念 312 11.3.12 静态方法何以为“静态” 314 11.4 变量的修饰符 316 11.4.1 变量方法皆成员 317 11.4.2 变量的访问控制符 317 11.4.3 使用private修饰类的成员变量 318 11.4.4 使用private,然后呢? 320 11.4.5 变量的覆盖 322 11.4.6 使用final修饰成员变量 325 11.4.7 静态成员变量 326 11.4.8 局部变量的修饰符 326 11.4.9 当final遇到引用类型成员变量 327 11.5 小结:修饰符作用大 328 11.6 习题 330 第12章 接口 331 教学视频:29分钟 12.1 自行车带来的问题 331 12.1.1 记录马路上的车辆 331 12.1.2 引发问题的自行车 335 12.1.3 仔细分析recordTransport()方法 338 12.2 初用接口 339 12.2.1 准备好需要用到的类 339 12.2.2 认识接口的代码组成 340 12.2.3 什么是接口 341 12.2.4 使用接口仅需一步——实现接口 342 12.2.5 接口——让类集多重类型于一身 344 12.2.6 简化recordTransport()方法 347 12.3 再探接口 349 12.3.1 重温上节中的程序 349 12.3.2 面向接口编程 351 12.3.3 话说“抽象” 353 12.3.4 接口大瘦身 355 12.3.5 实现多个接口 355 12.3.6 接口中的变量 357 12.3.7 接口的继承 358 12.3.8 匹配抽象方法中的类型 359 12.3.9 空接口 361 12.4 小结:接口的难点在于何时使用 362 12.5 习题 364 第13章 抽象类和内部类 365 教学视频:26分钟 13.1 抽象类(Abstract Class) 365 13.1.1 不知道怎么打招呼的Person类 365 13.1.2 当类中有了抽象方法 367 13.1.3 抽象类语法详解 368 13.1.4 理解抽象类的作用 369 13.2 内部类的分类(Inner Class) 370 13.2.1 成员内部类 370 13.2.2 局部内部类 372 13.3 成员内部类 374 13.3.1 使用成员内部类 374 13.3.2 成员内部类的修饰符 375 13.3.3 在类外部使用内部类 376 13.3.4 非静态内部类的特性 378 13.3.5 外部类访问成员内部类中的属性 382 13.3.6 静态成员内部类 383 13.4 局部内部类 384 13.4.1 局部内部类之“局部” 385 13.4.2 局部内部类之“内部类” 386 13.4.3 使用局部内部类 388 13.5 匿名内部类(Anonymous inner classes) 389 13.5.1 准备工作 389 13.5.2 匿名内部类的语法 389 13.5.3 通过接口使用匿名类 390 13.5.4 通过抽象类使用匿名类 391 13.6 类,这样一路走来 391 13.7 小结:丰富多彩的类 395 13.8 习题 397 第14章 Java异常处理机制 398 教学视频:36分钟 14.1 认识异常 398 14.1.1 异常什么时候发生 398 14.1.2 异常是什么 401 14.1.3 Java异常机制的流程 401 14.2 抛出异常 403 14.2.1 异常类的父类——Throwable 403 14.2.2 在代码中使用throw抛出一个异常 404 14.2.3 在方法声明中使用throws 407 14.2.4 构造自定义异常类 409 14.2.5 使用自定义异常类 410 14.3 异常的传递 411 14.3.1 抛出最确切的异常类型 411 14.3.2 Java异常的传递 412 14.3.3 图说Java异常的传递 414 14.4 异常的处理 418 14.4.1 把异常捉住 418 14.4.2 图说异常处理流程 421 14.4.3 多类异常,一并处理 424 14.4.4 try-catch-finally语句 426 14.4.5 try-finally语句 431 14.4.6 好好利用catch语句 432 14.5 异常的类型 433 14.5.1 3个类的继承关系 433 14.5.2 必须处理的Exception类 434 14.5.3 灵活掌握的RuntimeException类 434 14.5.4 不用处理的Error类 435 14.6 小结:终止错误的蔓延 435 14.7 习题 437 第15章 多线程编程 438 教学视频:1小时14分钟 15.1 线程——执行代码的机器 438 15.1.1 线程——执行代码的基本单位 438 15.1.2 演奏会模型 440 15.2 Java中的线程编程 443 15.2.1 线程类Thread 443 15.2.2 覆盖Thread类的run()方法 444 15.2.3 使用Runnable接口 446 15.2.4 两个线程 448 15.3 深入学习Thread类 449 15.3.1 线程的名字 449 15.3.2 得到当前的线程 451 15.3.3 让线程“沉睡” 453 15.4 多个线程的故事 457 15.4.1 一个有多个线程的程序 457 15.4.2 复印社模型 459 15.4.3 一个简单的复印社例程 461 15.5 多个线程的同步 463 15.5.1 线程同步之synchronized关键字 463 15.5.2 深入学习synchronized关键字 468 15.5.3 静态同步方法 469 15.5.4 非静态的同步方法 472 15.5.5 银行的麻烦——账户乱套了 474 15.5.6 多角度理解同步方法 481 15.5.7 闲话同步方法的使用 484 15.5.8 同步代码块 485 15.5.9 锁(Lock) 486 15.5.10 线程同步之wait()和notify()方法 488 15.5.11 wait和notify的顺序 491 15.6 小结:线程——代码执行器 494 15.7 习题 495 第3篇 Java语言编程进阶 第16章 如何学习本篇 498 教学视频:15分钟 16.1 多想多写多练 498 16.2 术业有专攻 498 16.3 拆分问题,逐个击破 500 16.4 阅读Javadoc 500 16.5 小结:大练兵马上开始 506 16.6 习题 507 第17章 编程常用知识 508 教学视频:18分钟 17.1 再谈对象的比较 508 17.1.1 hashcode()方法 508 17.1.2 equals()方法 509 17.1.3 对象的比较equals()方法 509 17.2 Java中的集合类框架 510 17.2.1 集合类框架中的接口 510 17.2.2 List接口 511 17.2.3 使用ArrayList 512 17.2.4 Set接口 516 17.2.5 使用HashSet类 517 17.2.6 List与Set 518 17.3 泛型简介 518 17.3.1 没有泛型时的程序 519 17.3.2 使用泛型——避免强制类型转 520 17.4 Map接口 522 17.4.1 认识Map 522 17.4.2 使用HashMap 523 17.5 字符集和编码 524 17.5.1 字符集 524 17.5.2 编码 525 17.5.3 关于字符集的小程序 526 17.6 小结:编程需要打好基础 529 17.7 习题 530 第18章 Java文件编程和Java文件I/O 531 教学视频:9分钟 18.1 Java中的文件编程 531 18.1.1 File类 531 18.1.2 创建和删除文件 532 18.1.3 列出文件和文件夹 533 18.1.4 重命名文件 535 18.2 Java的I/O编程 536 18.2.1 理解Java中的Stream 536 18.2.2 向文件中写入数据 538 18.2.3 从文件中读取数据 539 18.2.4 从控制台读取数据 541 18.2.5 使用输出流写入数据 543 18.2.6 使用输入流读取数据 545 18.3 小结:Java中的文件类和输入输出机制 546 18.4 习题 547 第19章 Java Socket编程 548 教学视频:8分钟 19.1 IP地址和端口号 548 19.1.1 IP地址——计算机的标识 548 19.1.2 端口号——通信的窗口 549 19.1.3 网络,IP地址和端口号 551 19.2 Java TCP编程 551 19.2.1 数据传输协议 552 19.2.2 TCP的数据传输模式 552 19.2.3 第一个TCP小程序 553 19.3 Java UDP编程 557 19.3.1 UDP的数据传输模式 557 19.3.2 使用UDP协议收发数据 558 19.3.3 TCP和UDP的区别 560 19.4 小结:让程序伸向整个网络 561 19.5 习题 561 第20章 Java Swing编程 562 教学视频:14分钟 20.1 Java Swing编程简介 562 20.1.1 图形用户界面编程简介 562 20.1.2 组件 563 20.1.3 布局管理器(Layout Manager) 563 20.1.4 事件处理(Event Handling) 564 20.2 Swing基本组件 565 20.2.1 窗口(JFrame) 565 20.2.2 Swing的线程 567 20.2.3 Swing组件的鼻祖——JComponent 567 20.2.4 Swing面板类 568 20.2.5 Swing中的标签 568 20.2.6 Swing中的文本框 570 20.2.7 Swing中的文本域 571 20.2.8 Swing中的组合框 572 20.2.9 Swing中的按钮 573 20.3 Swing的布局管理器 574 20.3.1 最简单的FlowLayout 574 20.3.2 东南西北中之BorderLayout 574 20.3.3 平均分割之——GridLayout 576 20.3.4 最强大的布局管理器——GridBagLayout 577 20.3.5 使用多个布局管理器 579 20.4 Swing的事件处理 581 20.4.1 事件的传递和封装 581 20.4.2 事件监听器——事件的处理者 582 20.4.3 Swing事件处理的机制 584 20.4.4 事件监听器的编写 586 20.4.5 如何学习更多的事件 588 20.5 小结:从此不再依赖控制台 588 20.6 习题 588 第21章 编程,需要的是想象力和恒心 589 教学视频:13分钟 21.1 编程的前奏 589 21.1.1 细数手中的积木 589 21.1.2 发挥想象力 590 21.1.3 确定程序的功能 591 21.2 聊天窗口程序 591 21.2.1 聊天程序设计 591 21.2.2 设计程序运行效果 593 21.2.3 UDP消息收发模块 595 21.2.4 图形用户界面模块 598 21.2.5 消息处理模块 600 21.2.6 一个更通用的聊天程序 601 21.3 小结:编程是必不可少的锻炼 602 21.4 习题 602 第22章 JDBC入门 603 教学视频:11分钟 22.1 JDBC的基本API 603 22.1.1 JDBC是什么 603 22.1.2 DriverManager——驱动管理器 605 22.1.3 Connection接口 606 22.1.4 Statement接口 606 22.1.5 PreparedStatement接口 606 22.1.6 ResultSet接口 607 22.1.7 JDBC-ODBC桥 607 22.2 一个操作数据库的简单程序 608 22.2.1 程序的执行结果 608 22.2.2 程序设计与模块划分 609 22.2.3 准备好数据源 610 22.2.4 数据库操作模块的实现 610 22.2.5 图形用户界面模块的实现 611 22.3 小结:强大的JDBC标准 613 22.4 习题 613
Java开发技术大全 电子版 第1篇Java基础知识入门. 第1章Java的开发运行环境2 1.1Java的运行环境与虚拟机2 1.2Java的开发环境4 1.2.1JDK的安装4 1.2.2如何设置系统环境变量6 1.2.3编译命令的使用8 1.2.4解释执行命令的使用10 1.2.5UltraEdit的使用11 1.3一个简单的Java应用程序14 1.4一个简单的Java小程序16 1.5本章小结18 第2章Java语言基础19 2.1Java语言的特点19 2.2Java程序的构成21 2.3数据类 型23 2.3.1基本数据类型23 2.3.2常量25 2.3.3变量26 2.3.4整型数据27 .2.3.5浮点型数据29 2.3.6字符型数据30 2.3.7布尔型数据32 2.3.8变量赋初值33 2.3.9变量的作用域34 2.3.10数据类型转换34 2.4运算符与表达式37 2.4.1算术运算符和算术表达式38 2.4.2关系运算符和关系表达式43 2.4.3逻辑运算符和逻辑表达式44 2.4.4条件运算符和条件表达式48 2.4.5位运算符和位运算表达式50 2.4.6赋值运算符和赋值表达式53 2.4.7表达式的求值顺序55 2.5流程控制语句58 2.5.1三种基本控制结构58 2.5.2表达式语句和空语句59 2.5.3块语句60 2.5.4if~else分支语句61 2.5.5多路分支switch~case语句69 2.5.6当型循环while语句71 2.5.7直到型循环do~while语句72 2.5.8当型循环for语句74 2.5.9循环的嵌套78 2.5.10跳转语句break80 2.5.11跳转语句continue82 2.6程序文本的风格84 2.6.1注释84 2.6.2程序的格式编排87 2.7基础语法实战演习88 2.7.1判断闰年88 2.7.2求最大公约数和最小公倍数89 2.7.3Fibonacci数列90 2.7.4逆向输出数字91 2.7.5求水仙花数92 2.7.6输出图形93 2.7.7输出九九口诀表94 2.8本章小结95 第2篇Java面向对象编程 第3章对象和类98 3.1面向对象的基本概念98 3.1.1对象98 3.1.2类99 3.1.3消息101 3.1.4面向对象的4个基本特征101 3.2类与对象104 3.2.1类的基本结构104 3.2.2类的声明104 3.2.3创建类体105 3.2.4对象的生命周期106 3.2.5对象的创建106 3.2.6对象的使用108 3.2.7对象的释放和垃圾收集机制108 3.3成员变量的定义与使用109 3.3.1成员变量的定义109 3.3.2成员变量的访问权限110 3.3.3实例成员变量和静态成员变量114 3.4方法的定义和实现116 3.4.1方法的声明117 3.4.2创建方法体与return语句117 3.4.3局部变量和成员变量的区别119 3.4.4方法的访问权限121 3.5方法的调用121 3.5.1方法调用的形式121 3.5.2方法调用的参数123 3.5.3隐含参数this127 3.6构造方法128 3.6.1无参数构造方法的定义和使用129 3.6.2带参数构造方法的定义和使用131 3.6.3this关键字和构造方法的调用132 3.7静态方法133 3.7.1静态方法的声明和定义134 3.7.2静态方法和实例方法的区别134 3.7.3静态代码块136 3.7.4再论静态成员变量137 3.8main()方法和命令行参数139 3.9结束方法141 3.10本地方法141 3.11本章小结144 第4章继承与多态145 4.1继承的基本原理145 4.2子类对父类的继承146 4.3属性隐藏和方法的覆盖148 4.3.1属性的隐藏148 4.3.2方法的覆盖151 4.4构造方法的继承154 4.5super的使用156 4.5.1用super引用父类的成员156 4.5.2使用super调用父类的构造方法157 4.6继承的内部处理158 4.7多态的基本概念159 4.8重载159 4.8.1普通方法的重载160 4.8.2构造方法的重载161 4.8.3重载的解析163 4.8.4重载与覆盖的区别165 4.9运行时多态165 4.9.1实例方法的运行时多态165 4.9.2成员变量运行时的表现167 4.9.3静态方法运行时
看到很多人都分卷打包的,下载很是不方便,还浪费积分,我就整合压缩打包到一个包里面,里面包含全部源码 源码目录如下: 第1部分(2个程序包) HelloWorld.zip 01.Java入门样例HelloWorld demo.zip 03.Eclipse入门样例demo 第2部分(3个程序包) javasyntax.zip 05.Java核心语法详解 javaoop.zip 06.Java面向对象编程(计算器) javaexception.zip 07.Java面向对象编程扩展(计算器异常捕捉实例) 第3部分(5个程序包) javaio.zip 09.Java输入/输出流 javavi.zip 09.Java输入/输出流上机作业参考(文本编辑器) javathread.zip 10.Java多线程编程(线程池、生产者消费者、存取款实例) javautil.zip 11.Java常用实体类 javaxml.zip 14.XML属性文件 第4部分(6个程序包) javagui.zip 15.Java GUI库对比实例 javaawt.zip 16.AWT图形界面开发——Java文本编辑器 javamedia.zip 17.AWT多媒体编程——录音机、MP3播放器、视频拍照、视频播放器 javaswing.zip 18.Swing图形界面开发——Java文本编辑器 javaswt.zip 19.SWT图形界面开发——Java文本编辑器 javajface.zip 20.SWT增强组件库JFace 第5部分(5个程序包) javaapplet.zip 21.Applet网络组件——电子相册 javanet.zip 22.Java网络编程详解(Socket/UDP实例、简单聊天系统) javanio.zip 23.NIO非阻塞通信(Socket/UDP实例、简单聊天系统) javarmi.zip 24.RMI编程(HelloWorld例、计算器实例) javacorba.zip 25.Corba编程(HelloWorld例、计算器实例) 第6部分(4个程序包) javareflection.zip 26.Java反射机制与动态代理 javageneric.zip 27.Java泛型编程 javaannotation.zip 28.Java注释符编程 javafeature.zip 29.Java5.0语言新特性

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值