Minecraft(我的世界)中文论坛

标题: 【万年坑】【本章完结】Java高手训练营第九章:异常处理

作者: ufof    时间: 2015-11-6 17:50
标题: 【万年坑】【本章完结】Java高手训练营第九章:异常处理
本帖最后由 ufof 于 2015-12-11 03:21 编辑



9.1 Throwable体系



9.1.1 Throwable类概述

无论技术多么精通的程序员永远都做不到让程序万无一失的。我们之前编程的过程中,程序总有编译不通过的时候。根据Java的面向对象规则,就算是错误/异常也是对象。java.lang.Throwable类是所有异常/错误的父类。Throwable的意思是“可抛出的”。在学习如何解决/抛出异常之前,我们先来学会这个体系。

9.1.2 异常和错误

Throwable类有两个直接子类:异常(
Exception)和错误(Error)。从表面上来看,这两个词貌似没有什区别,但是在编程当中是必须要区分开的。

总而言之,异常和错误的区别在于:错误一般是和虚拟机有关的问题,较为严重。例如找不到类、系统崩溃、虚拟机错误等。错误不能被程序员人为的解决/抛出。唯一的解决方式是改变源代码。

异常没有错误那么的严重,一般是一些小的问题:例如除零、数组越界等。异常可以被程序员解决/抛出。本章的重点就是异常。

9.1.3 虚拟机的默认处理Throwable方式

我们人为的制造一个有异常的程序。

  1. import java.util.Scanner;

  2. class ExceptionDemo{
  3.    
  4.     public static void main(String[] args){
  5.         Scanner s = new Scanner(System.in);
  6.         System.out.println("请输入第一个数字:");
  7.         int num1 = s.nextInt();
  8.         System.out.println("请输入第二个数字:");
  9.         int num2 = s.nextInt();
  10.         
  11.         System.out.println("这两个数的商是:"+num1/num2);   //打印两个数的商
  12.         System.out.println("感谢使用!");
  13.     }
  14. }
复制代码
结果:







在这个程序当中,用户键入的除数是0。根据数学常识,除零是不可接受的。因此,在计算num1/num2时,虚拟机发现num2为0,一个ArithmeticException(算数异常)实例被抛出。

当虚拟机发现了一个Throwable时,会首先打印跟踪栈。跟踪栈是结果中最后的两行英文,主要的内容是
Throwable的类型、Throwable的描述、出现Throwable的位置。

程序在打印完商之后,也应当输出“感谢使用”。但是没有打印。所以说,出现Throwable时,程序立刻终止。

程序员对于异常可以有两种处理方式:第一种是捕捉(也就是通过try、catch、finally),第二种是抛出。下一节当中,我们来学习第一种。

本章小结



9.2 try、catch、finally



9.2.1 捕捉异常概述

上一节中,我们提到了处理异常的两种方式:捕捉或抛出。当方法中知道如何解决这个异常,不需要让上级调用者解决,应当使用捕捉方法。Java为我们提供try、catch、finally这三个语句块来捕捉异常。

9.2.2 语法

三个语句块的使用方法如下:
  • try{}:有可能发生异常的语句块
  • catch(异常类型 实例名){}:如果try中出现了指定的异常类型,进入该catch语句块(可以有若干个)
  • finally{}:无论错误是否发生,都要执行的语句块

捕捉异常后,异常便会被解决。虚拟机不再终止程序并打印跟踪栈。

9.2.3  实例

我们写一个实例:

  1. class TryCatchFinallyDemo{
  2.     public static void main(String[] args){
  3.         int num1 = 10;
  4.         int num2 = 0;
  5.         try{
  6.             //运算num1/num2,有可能出现ArithmeticException
  7.             System.out.println("num1/num2="+divide(num1,num2));
  8.             System.out.println("运算完成。");
  9.         }
  10.         catch(ArithmeticException e){        //捕捉ArithmeticException
  11.             System.out.println("发生数学异常");
  12.         }
  13.         
  14.         System.out.println("程序结束。");
  15.     }
  16.    
  17.     public static int divide(int a, int b){  //除法方法
  18.         return a/b;                             //返回a/b
  19.     }
  20. }
复制代码
结果:



那么这个程序究竟是什么流程呢?

这个程序当中的第七行代码,“divide(num1,num2)”中,程序就相当于执行了一个new ArithmeticException()。这个对象会赋给catch中的“ArithmeticException e”实例。就相当于是“ArithmeticException e = new ArithmeticException()”。

而且可以通过这个程序可以观察到两点:

9.2.4 获取异常信息


在catch块当中,可以通过异常的实例来获取异常的信息。Throwable类中有三个方法供我们获取信息:


  1. class TryCatchFinallyDemo{
  2.     public static void main(String[] args){
  3.         int num1 = 10;
  4.         int num2 = 0;
  5.         try{
  6.             System.out.println("num1/num2="+divide(num1,num2));
  7.             System.out.println("运算完成。");
  8.         }
  9.         catch(ArithmeticException e){
  10.             System.out.println(e.toString());    //打印异常的toString()
  11.         }
  12.         
  13.         System.out.println("程序结束。");
  14.     }
  15.    
  16.     public static int divide(int a, int b){
  17.         return a/b;
  18.     }
  19. }
复制代码
结果:



在这个程序当中,我在catch块中打印了e.toString()。结果是异常类名+信息。

  1. class TryCatchFinallyDemo{
  2.     public static void main(String[] args){
  3.         int num1 = 10;
  4.         int num2 = 0;
  5.         try{
  6.             System.out.println("num1/num2="+divide(num1,num2));
  7.             System.out.println("运算完成。");
  8.         }
  9.         catch(ArithmeticException e){
  10.             System.out.println(e.getMessage());    //打印异常的getMessage()
  11.         }
  12.         
  13.         System.out.println("程序结束。");
  14.     }
  15.    
  16.     public static int divide(int a, int b){
  17.         return a/b;
  18.     }
  19. }
复制代码
结果:



这次我打印的是e.getMessage()。可以看出来,仅仅有异常的信息,没有类型。

  1. class TryCatchFinallyDemo{
  2.     public static void main(String[] args){
  3.         int num1 = 10;
  4.         int num2 = 0;
  5.         try{
  6.             System.out.println("num1/num2="+divide(num1,num2));
  7.             System.out.println("运算完成。");
  8.         }
  9.         catch(ArithmeticException e){
  10.             e.printStackTrace();                     //打印跟踪栈
  11.         }
  12.         
  13.         System.out.println("程序结束。");
  14.     }
  15.    
  16.    public static int divide(int a, int b){
  17.         return a/b;
  18.     }
  19. }
复制代码
结果:



打印跟踪栈其实和之前我们演示的虚拟机默认处理Throwable的方式看上去一样。推荐大家使用打印跟踪栈的方式获取异常的信息,因为异常类、信息、出现地点应有尽有。较为详细。

9.2.5 多个catch

如果try中的语句块有可能会出现多个异常,需要使用多个catch块来进行处理。

这里我们写一个程序:可以通过Scanner类获取用户的输入。输入两个数后进行除法运算。这个程序有两个潜在的异常:


ps: InputMismatchException在java.util包下,所以说也需要导包。


所以说,我们需要通过两个catch块进行处理。

  1. import java.util.*;

  2. class TryCatchFinallyDemo{
  3.     public static void main(String[] args){
  4.         Scanner s = new Scanner(System.in);
  5.         int num;
  6.         int num2;
  7.         try{
  8.             System.out.println("请输入第一个数字:");
  9.             num = s.nextInt();
  10.             
  11.             System.out.println("请输入第二个数字:");
  12.             num2 = s.nextInt();
  13.             
  14.             System.out.println("这两个数字的商是:"+num/num2);
  15.         }
  16.         catch(ArithmeticException e){                 //捕捉运算异常
  17.             System.out.println("不能除以0");
  18.         }
  19.         catch(InputMismatchException e){           //捕捉输入错误异常
  20.             System.out.println("输入有误");
  21.         }
  22.     }
  23. }
复制代码
结果1(除0):



结果2(输入有误):



相信多个catch块不难理解。但是问题来了:要是我的try语句块中有可能出现的异常太多了,不可能一个一个的把所有catch列举出来,该怎么办呢?

大家还记不记多态?

  1. import java.util.*;

  2. class TryCatchFinallyDemo{
  3.     public static void main(String[] args){
  4.         Scanner s = new Scanner(System.in);
  5.         int num;
  6.         int num2;
  7.         try{
  8.             System.out.println("请输入第一个数字:");
  9.             num = s.nextInt();
  10.             
  11.             System.out.println("请输入第二个数字:");
  12.             num2 = s.nextInt();
  13.             
  14.             System.out.println("这两个数字的商是:"+num/num2);
  15.         }
  16.         catch(Exception e){            //捕捉Exception,凡是所有Exception类的子类都能被捕捉
  17.             System.out.println("出现异常");
  18.         }
  19.     }
  20. }
复制代码

这次,我不再捕捉两个异常。我直接捕捉他们的父类:Exception。我们曾经提过,在try块中出现异常,会new出来一个异常对象,并赋给catch中的实例。如果发生了算数异常,就相当于“Exception e = new ArithmeticException()”,如果发生输入错误异常,相当于“Exception e = new InputMismatchException()”。这两个是不是面向对象特点中的多态?这真的是一个很方便的事情。

但是一定要记住:先捕捉一些最有可能发生的小异常,最后再捕捉父类。虽说直接捕捉Exception方便,但是不清晰、具体。

9.2.6 finally

finally语句块是可选的。其中的代码是无论出错与否都要执行的语句。

  1. import java.util.*;

  2. class TryCatchFinallyDemo{
  3.     public static void main(String[] args){
  4.         Scanner s = new Scanner(System.in);
  5.         int num;
  6.         int num2;
  7.         try{
  8.             System.out.println("请输入第一个数字:");
  9.             num = s.nextInt();
  10.             
  11.             System.out.println("请输入第二个数字:");
  12.             num2 = s.nextInt();
  13.             
  14.             System.out.println("这两个数字的商是:"+num/num2);
  15.         }
  16.         catch(Exception e){
  17.             System.out.println("出现异常");
  18.         }
  19.         finally{     //一定执行的语句
  20.             System.out.println("程序结束");
  21.         }
  22.     }
  23. }
复制代码
结果:



finally语句块一般有什么用呢?一般适用于关闭资源、释放锁等。无论出现异常与否,都需要释放、关闭资源。finally在IO流技术中十分常用。然而在本章中并不是我们的重点。

本章小结


9.3 使用throws声明异常



9.3.1 throws概述

上一节中,我们学习了处理异常的第一种方式:捕捉。这种处理方式是在本方法中直到如何解决有可能发生的异常的情况下使用的。如果本方法不知道如何处理有可能发生的异常,需要由上一级调用者处理,需要声明异常。上一级调用者也一样,要么捕捉,要么接着往上声明。如果主方法也没有捕捉,声明给了虚拟机,虚拟机就会使用它的默认处理方式解决异常。

9.3.2 语法

如果一个方法需要声明异常,通过这个格式声明:

  1. 若干个修饰符 返回值类型 方法名(参数列表) throws  有可能的异常,有可能的异常,...{
  2.    //若干代码
  3. }
复制代码

我们使用上一节中的除法方法来讲解:

  1. class ThrowsDemo{
  2.     public static double divide(int a, int b) throws Exception{   //抛出异常
  3.         return a/b;
  4.     }
  5.    
  6.     public static void main(String[] args){
  7.         System.out.println(divide(2,1));
  8.     }
  9. }
复制代码
结果:



学生提问:为什么不抛出ArithmeticException,而是Exception?

答:这是为了方便演示。ArithmeticException是RuntimeException的子类,这种特殊的异常即使不声明也可以。我们会讲解。为了让你们了解声明异常的本质,我先暂时抛出Exception。

可以发现,虽说没有除零,但是这段程序是编译失败的。main()方法调用了divide()方法。divide()方法声明了一个异常。main()是divide()的上级调用者,所以说main()方法中必须要选择:①捕捉、②继续声明

我们演示一下捕捉:

  1. class ThrowsDemo{
  2.     public static double divide(int a, int b) throws Exception{
  3.         return a/b;
  4.     }
  5.    
  6.     public static void main(String[] args){
  7.         try{
  8.             System.out.println(divide(1,0));   //由于divide()方法声明Exception,必须捕捉或声明
  9.         }
  10.         catch(Exception e){   //捕捉Exception
  11.             e.printStackTrace();
  12.         }
  13.         
  14.         System.out.println("程序结束。");
  15.     }
  16. }
复制代码
结果:



catch块后面的“程序结束”被打印了,所以说异常被解决了,程序正常运行。

如果main()方法也声明:

  1. class ThrowsDemo{
  2.     public static double divide(int a, int b) throws Exception{
  3.         return a/b;
  4.     }
  5.    
  6.     public static void main(String[] args) throws Exception{  //主方法声明异常
  7.         System.out.println(divide(1,0));        
  8.         System.out.println("程序结束。");
  9.     }
  10. }
复制代码
结果:



catch块后面的“程序结束”没有被打印。这是因为主方法的上级调用者是虚拟机。虚拟机一旦收到了异常,就会使用它的默认处理方式:打印跟踪栈并终止程序。所以说后面的字符串没有被打印。

9.3.3 RuntimeException类

RuntimeException类是Exception类的子类。其实我们之前的ArithmeticException是RuntimeException的子类。RuntimeException称为运行时异常。

顾名思义,运行时异常仅在运行时发生。如果一个方法有可能发生运行时异常,这个方法不需要声明这种异常
而且,如果一个方法声明了运行时异常,其的上级调用者不需要进行捕捉或继续声明。

  1. class ThrowsDemo{
  2.     public static double divide(int a, int b)throws ArithmeticException{
  3.         return a/b;
  4.     }
  5.    
  6.     public static void main(String[] args){
  7.         System.out.println(divide(1,0));        //没有进行任何处理,但是编译通过        
  8.         System.out.println("程序结束。");
  9.     }
  10. }
复制代码

那么这是为什么?我们之前写除法方法的时候,方法和代码没有任何问题。导致这个异常的原因是逻辑错误(无法除零)而非代码错误。由于不是代码出错而是逻辑出错,一般是用户在使用过程中出现了问题(也就是输入除零)。所以说这种异常不应当被程序员解决。应当将这个异常一直向上抛,抛到用户层当中作为提示。如果这种异常显示的在方法上throws,上一级调用者也就会显式的处理,这样就达不到抛给用户的需求了

本章小结



9.4 使用throw手动抛出异常



9.4.1 throw概述

我们之前在通过除零演示异常时,异常的抛出是有系统自己完成的。也就是只要除零,系统会自动抛出一个异常,我们不需要做任何事情。不过在实际开发当中,你自己定义的功能肯定有自己出错的方式,所以说Java为我们提供了手动抛出异常的语句:throw。我们学了自定义异常以后还可以通过throw抛出自己的异常。

9.4.2 throw的使用

throw在方法中使用。格式如下:

  1. throw 异常对象;
复制代码

我们需要自己实例化一个异常类。不过由于只需要使用一次,可以使用匿名对象的方式。实例化涉及到构造方法,我们简单的来学习一下Throwable类的常用两个构造方法:


好的,现在我们定义一个除法方法。如果除数为0,抛出ArithmeticException,并附上信息。

  1. class ThrowDemo{
  2.     public static void main(String[] args){
  3.         System.out.println(divide(1,0));
  4.     }
  5.    
  6.     public static double divide(int a, int b){
  7.         if(b==0){        //如果除数为0
  8.              throw new ArithmeticException("不能除0!");   //抛出异常
  9.         }
  10.         System.out.println("算数成功");
  11.         return a/b;
  12.     }
  13. }
复制代码
结果:




在divide()方法中,对参数b进行了是否等于0的判断。如果是,抛出一个ArithmeticException,这个对象有详细信息,可以在结果当中看到。

而且,大家可以发现,后面的“算数成功”没有被打印,可以发现,当一个方法抛出一个异常时,该方法结束

此外,如果一个方法抛出的异常不是RuntimeException或其子类,方法上必须声明它抛出的异常

  1. class ThrowDemo{
  2.     public static void main(String[] args){
  3.         System.out.println(divide(1,0));
  4.     }
  5.    
  6.     public static double divide(int a, int b){
  7.         if(b==0){        //如果除数为0
  8.              throw new Exception("不能除0!");    //仅抛出Exception,而非运行时的ArithmeticException
  9.         }
  10.         System.out.println("算数成功");
  11.         return a/b;
  12.     }
  13. }
复制代码
结果:



这次我仅仅抛出一个Exception,由于其是RuntimeException的父类而不是子类,在方法中抛出Exception必须要在这个方法上声明这个异常。

  1. class ThrowDemo{
  2.     public static void main(String[] args){
  3.         System.out.println(divide(1,0));
  4.     }
  5.    
  6.     public static double divide(int a, int b) throws Exception{
  7.         if(b==0){        //如果除数为0
  8.              throw new Exception("不能除0!");    //仅抛出Exception,而非运行时的ArithmeticException
  9.         }
  10.         System.out.println("算数成功");
  11.         return a/b;
  12.     }
  13. }
复制代码
这次,我在divide()方法上声明了这个异常,编译才能通过。


本章小结



9.5 自定义异常



9.5.1 自定义异常概述

在实际的开发当中,光使用Java类库为我们提供的异常是远远不够的。有一些程序的异常是这个程序独有的,这个时候需要自定义异常。然而,自定义异常要是要起作用,必须要手动的使用throw抛出。自定义异常的捕捉、声明也和前面讲的一模一样。现在我们来开始学习如何自定义一个异常。

9.5.2 自定义异常方式

我们之前接触的ArithmeticException、InputMismatchException等,都是类,因为万物皆对象。想要自定义异常,也是要写一个类,让这个类继承Exception(如果想让它成为运行时异常,需要继承RuntimeException),然后就可以了。很简单。

  1. class CustomizeExceptionDemo{
  2.     public static void main(String[] args)throws MyException{
  3.         throw new MyException();  //抛出这个异常
  4.     }
  5. }

  6. class MyException extends Exception{}  //自定义异常:MyException
复制代码
结果:



在主方法中抛出我们自定义的异常,可以在跟踪栈中看出,我们定义的这个异常的确是有效了。但是这个异常类还有一个问题:没有详细信息。

我们在讲throw的时候讲过了,通过Throwable的构造方法来定义一个详细信息。在我们这个类中也要定义一个这样的构造方法。

  1. class MyException extends Exception{
  2.     public MyException(String msg){  //有参数构造方法
  3.         
  4.     }
  5.    
  6.     public MyException(){                 //无参构造方法
  7.         
  8.     }
  9. }
复制代码
但是,在有参数的构造方法中,我们究竟如何让msg的参数作为异常的详细信息呢?我们知道,Throwable拥有这样的构造方法,而且Throwable是MyException的父类,所以说通过我们在面向对象中学过的super关键字将这个msg传入。

  1. class MyException extends Exception{
  2.     public MyException(String msg){
  3.         super(msg);        //调用父类的构造方法,将msg传入
  4.     }
  5.    
  6.     public MyException(){
  7.         
  8.     }
  9. }
复制代码

现在这个异常类已经算是较为完善的了。我们用这个有参数的构造方法来throw一下看一看:

  1. class CustomizeExceptionDemo{
  2.     public static void main(String[] args)throws MyException{
  3.         throw new MyException("这是异常的详细信息");  //抛出时使用有参构造方法
  4.     }
  5. }

  6. class MyException extends Exception{
  7.     public MyException(String msg){
  8.         super(msg);        //调用父类的构造方法,将msg传入
  9.     }
  10.    
  11.     public MyException(){
  12.         
  13.     }
  14. }
复制代码
结果:



好的!现在我们已经了解了如何定义一个自己的异常类,相信十分简单。我们通过一个实例来巩固一下知识。

9.5.3  实例

在这个例子当中,我们要写一个除法方法。这个方法有两个潜在的异常:


大家会注意到,由于IllegalNumberException是由用户传入不当的参数造成的,不需要进行捕捉,所以说然这个类继承RuntimeException会更好。

  1. class CustomizeExceptionDemo{
  2.     public static void main(String[] args){
  3.         System.out.println(divide(150,-3));
  4.     }
  5.    
  6.     public static double divide(int a, int b){
  7.         if(b==0){
  8.             throw new ArithmeticException("不能除零");
  9.         }
  10.         if(a>100 || a<0 || b>100 || b<0){    //如果a>100 或 a<0 或 b>100 或 b<0
  11.             throw new IllegalNumberException("本程序要求:被除数和除数都在0到100之间");
  12.             //抛出异常
  13.         }
  14.         
  15.         return a/b;
  16.     }
  17. }

  18. class IllegalNumberException extends RuntimeException{    //自定义异常
  19.     public IllegalNumberException(){}
  20.     public IllegalNumberException(String msg){
  21.         super(msg);
  22.     }
  23. }
复制代码
结果:



在这个程序当中,我自定义了一个运行时异常,IllegalNumberException。需求是当被除数或除数>100或<0时抛出。所以说我在divide()方法中进行了判断,如果
被除数或除数>100或<0,那么就抛出我自定义的这个异常。

这项技术在开发当中是十分常用的,希望大家可以熟悉。

本章小结



以下为Java中常见的Runtime异常以及其的描述:

异常类名 描述
java.lang.ArithmeticException 当数学运算问题发生,该异常抛出。
java.lang.ArrayStoreException
当运行时发现数组中的元素与其类型不匹配该异常抛出。
  1. Object[] arr = new int[5];
  2. arr[0] = "abc"; //类型不匹配
复制代码
java.lang.ClassCastException 当对对象进行向下转换时,发现类型不匹配,该异常抛出。
  1. Object obj = "abc";
  2. Integer i = (Integer)obj; //类型不匹配
复制代码
java.lang.
ConcurrentModificationException
当一个集合正在被迭代器迭代时,此时若通过集合的方法修改集合的元素,会导致混乱和安全隐患,该异常抛出。
java.lang.
IllegalArgumentException
当方法不接收其传入的参数时,该异常抛出。
java.lang.
IndexOutOfBoundsException
当访问数组某个角标的元素时,该角标超出了数组的长度,该异常抛出。
  1. int[] arr = {1,2,3,4,5};
  2. System.out.println(arr[10]);  //arr没有第10个角标
复制代码
java.lang.
NegativeArraySizeException
当动态初始化一个数组时,其的长度被设置为负数,该异常抛出。
  1. int[] arr = new int[-1];
复制代码
java.lang.
NoSuchElementException
当通过集合的方法或迭代器迭代的方式访问集合中的元素时,若集合没有这个元素,该异常抛出。
java.lang.NullPointerException
当使用一个值为null的实例调用方法/字段时,该异常抛出。


[groupid=546]Command Block Logic[/groupid]
作者: duang2333    时间: 2015-12-7 19:59
这么好的教程居然没人
作者: 291837341    时间: 2015-12-8 17:40
楼主你好我想请问一下周目来获取 发射器里的东西
作者: DeathWolf96    时间: 2015-12-10 11:56

  1. try {
  2. throw new Throable();
  3. } catch(Throwable t) {
  4. }
复制代码


据说Throwable不能被捕捉……
作者: 辅助啊    时间: 2015-12-10 14:04
好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好
好好好好好好好好好好好好好好好好好好好好好好好好讚讚讚讚讚讚讚讚讚好好好好  
好好好好好好好好好好好好好好好好好好讚讚讚讚讚讚讚讚讚讚讚讚讚讚讚好好好好
好好好好好好好好好好好好好好好讚讚讚讚讚讚讚讚讚讚讚讚讚讚讚讚讚讚好好好好
好好好好好好好好好好好讚讚讚讚好讚讚讚讚讚讚讚讚讚讚讚好好好好好好好好好好
好好好好好好好好讚讚讚讚讚讚讚好讚讚讚好好讚讚讚讚讚好好好好好好好好好好好
好好好讚讚讚讚讚讚讚讚讚讚讚讚好好好好好好讚讚讚讚好好好好好好好好好好好好
好讚讚讚讚讚讚讚讚讚讚讚讚讚讚好好好好好好讚讚讚讚好好好好好好好好好好好好
好讚讚讚讚讚讚讚讚讚讚讚讚好好好好好好好讚讚讚讚讚讚讚讚讚讚讚好好好好好好
好讚讚讚讚讚讚讚讚讚讚讚讚好好好好好好讚讚讚讚讚讚讚讚讚讚讚讚讚好好好好好
好好讚讚讚讚讚讚讚讚讚讚好好好好好讚讚讚讚讚好好好讚讚讚讚讚讚讚好好好好好
好好好好好好好好讚讚讚讚好好好好好讚讚讚讚好好好好好好讚讚讚讚讚好好好好好
好好好好好好好好讚讚讚讚好好好好讚讚讚讚好好讚讚好好好讚讚讚讚讚好好好好好
好好好好好好好好讚讚讚讚好好好好讚讚讚讚好好讚讚讚讚好讚讚讚讚讚好好好好好
好好好好好好好好讚讚讚讚好好好好讚讚讚讚好好讚讚讚讚好讚讚讚讚讚好好好好好
好好好好好好好好讚讚讚讚好好好好讚讚讚讚好好讚讚讚好好讚讚讚讚讚好好好好好
好好好好好好好好讚讚讚讚好好好好讚讚讚讚好好讚讚讚好好讚讚讚讚讚好好好好好
好好好好好好好好讚讚讚讚好好好好讚讚讚讚好讚讚讚讚好好讚讚讚讚讚好好好好好
好好好好好好好好讚讚讚讚好好好好讚讚讚讚好讚讚讚讚好好讚讚讚讚讚好好好好好
好好好好好好好好讚讚讚讚好好好好讚讚讚讚好讚讚讚讚好好讚讚讚讚讚好好好好好
好好好好好好好好讚讚讚讚好好好好讚讚讚讚好讚讚讚讚好好讚讚讚讚讚好好好好好
好好好好好好好好讚讚讚讚好好好好讚讚讚好好讚讚讚讚好好讚讚讚讚讚好好好好好
好好讚讚好好好讚讚讚讚讚好好好好讚讚讚好好讚讚讚好好好讚讚讚讚讚好好好好好
好好讚讚讚讚讚讚讚讚讚讚好好好好好讚讚好好讚讚好好好好讚讚讚讚讚好好好好好
好好好讚讚讚讚讚讚讚讚讚好好好好好好好好讚讚讚好好好好讚讚讚讚好好好好好好
好好好好好讚讚讚讚讚讚讚好好好好好好好好讚讚讚好讚讚讚讚好好好好好好好好好
好好好好好好讚讚讚讚讚讚好好好好好好好讚讚讚讚好好讚讚讚讚讚好好好好好好好
好好好好好好好好好讚讚讚好好好好好好讚讚讚讚讚好好好讚讚讚讚讚讚讚好好好好
好好好好好好好好好好好好好好好好讚讚讚讚讚讚好好好好好讚讚讚讚讚讚好好好好
好好好好好好好好好好好好好好好讚讚讚讚讚讚好好好好好好讚讚讚讚讚讚讚好好好
好好好好好好好好好好好好好好讚讚讚讚讚好好好好好好好好好讚讚讚讚讚讚好好好
好好好好好好好好好好好好好讚讚讚讚讚好好好好好好好好好好好讚讚讚讚好好好好
好好好好好好好好好好好好讚讚讚好好好好好好好好好好好好好好好讚讚讚好好好好
好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好
作者: zzzzzzzabczz    时间: 2016-1-5 20:51
幽浮早上好
学习ing……
啃了啃《Thinking in java》
发现还是你这个更好懂{:10_522:}

如果我学完你这个是不是就能看懂那本书了?
作者: ufof    时间: 2016-1-5 22:26
zzzzzzzabczz 发表于 2016-1-5 04:51
幽浮早上好
学习ing……
啃了啃《Thinking in java》

学完了我的这个的确还是有提高的空间。读书的话是会更加懂点。
作者: 947132885    时间: 2016-1-24 18:52
恩,我发现现在java8中,除数为0的话会得到infinity,就是无限的意思....
作者: 947132885    时间: 2016-1-24 19:07
947132885 发表于 2016-1-24 18:52
恩,我发现现在java8中,除数为0的话会得到infinity,就是无限的意思....

额,好吧,看来刚才是个巧合,换成int果然不行。
作者: 2478003816    时间: 2016-2-1 10:34
学不会这个是不是就对制作mod完全No way     说实话我这个菜鸟对这些还不是很了解   我还要去了解这里面讲的一些基础   Exception   Error我也是认为没什么区别,没想到有这么大区别。啊心累   不知道你学这些学了多久    我希望我自己不是三分钟热度!
作者: ufof    时间: 2016-2-1 17:51
2478003816 发表于 2016-1-31 18:34
学不会这个是不是就对制作mod完全No way     说实话我这个菜鸟对这些还不是很了解   我还要去了解这里面讲 ...

关于数学其实要求不大,会四则运算就可以了,如果会二进制的话更好(可以了解底层运算机制);英语词汇量能到初中水平就行,像什么关键字这些都是实实在在的单词。

如果不想要半途而废的话可以找一些更有趣的方法来学习,本人推荐毕向东的Java视频,讲的幽默有趣,你可以去看看。