黑马程序员——对基础的补充

------- android培训java培训、期待与您交流! ----------

说明:该部分为1~10章节部分日志的补充。只收录了自己不熟练的部分和小知识点总结。

1-1:简单命令:

Dos命令:运行cmd

echo 也可以创建文件夹

rd或del:删除文件。前者只能删除空文件,或者先进入cd到最底层文件,从最低层往上层一层一层地删除;后者不用进入最低层文件夹就可以删除里面的一切内容和目录。

在文件路径下,用del *.txt 可以删除txt类型的文件。

1-5:

配置环境变量的小技巧:

为便于以后修改JDK的安装目录,又不对系统环境变量做修改,可以在系统环境变量中,用一个常量如JAVA_HOME代替可能会发生变动的值,用%%动态获取JAVA_HOME的值就可以了。比如系统环境变量原来设置的JDK路径值是C:\jdk6.0\bin; 可以用%JAVA_HOME%\bin代替,然后新建一个系统变量名:JAVA_HOME,设其值为:C:\jdk1.6.0,以后若改变jdk安装目录,则直接改动一下JAVA_HOME的值就可以了。

1-6:设置临时环境变量:

用set命令,设置后只在当前命令行有效。

在C盘根目录下(输入:cd\ 按回车即可),输入set 回车 可查看系统变量;set 变量名,可查看系统变量名 ;set 变量名=变量值 可临时修改系统环境变量值。 若要保留原有path路径值,可以set path=临时增加路径;%path% 这样就可以动态获取path原来的值了。 若在dos窗口输入start新开一个dos窗口,则会沿用刚才的临时设置。若用其他方式开启的则不沿袭。set path= ,即清空了path变量值。

1-8:如果执行一个类文件,要么切换到类所在当前路径,要么就是吧类的路径设置到classpath系统变量中去就可以保证任何地方都可以执行了。若临时设置,可以用set。

 

执行class文件是,系统是先找classpath,再找当前目录。知道找第一次找到相应的文件就停止。若路径结尾不加分号,则classpath路径下寻找不到后不会再去当前路径下寻找,带分号会,一般不要带分号(如果连续配置了多个路径,则最后一个路径不要带分号就可以了);另外一个点表示当前路径。如set classpath=.;c:\;d:\ 就是指在当前路径,c盘,d 盘路径下寻找。

而设置path时刚好相反,系统是先在当前路径寻找文件,再去path路径下寻找。

第二天:

2-1:

关键字数字不开头;main不是关键字,却被系统所识别。

常量名:每个字符都大写,单词间用下划线连接。

字符常量:将一个数字、字母、或符号用单引号标示

2-10 转义字符:

\n:换行。在liux系统里,换行用\n,在Windows里用\r\n 。而dos里直接用\n

\r :相当于按下回车键

总结的:路径分隔符在windows下是 \ ,//,或File.separator;在LInux下是 /。

如果你只在windows环境下用,前三种都可以;若考虑在linux下也可以正常运行,建议使用File.separator.

另外,说下换行符:\n:换行。在Windows里用\r\n,换行用\n。在liux系统里,在Mac下和 dos里直接用\n

2-11赋值与比较运算符

short x = 3;

x += 3;

//x = x + 3;这种写法会报错,而上面的写法不会。因为这是两次运算,加法和赋值,加法运算的结果是整型。

2-13 位运算符 (<< ,>>, >>>)

左移,右边用0补位;右移,左边按左边的数字补位(最左边是0补0,是1补1);若用三个大于号(>>>)右移,则左边一定用0补;左移或右移n位就相当于乘以或除以2的n次方。位运算是最快的运算。

2-14

一个数异或另一个数两次,结果还是那个数。此原理可用来加密、解密文件。

2-15

位运算经典实例:

(1)用最有效的方法算出2*8等于几:

用位运算里的移位:2 << 3;

(2)不通过其他变量,交换整型常数n 和m的值;

方法一:

n = n + m;//若m 和n的值很大,容易超出int范围。

m = n – m;

n = n – m;

方法二://方法二更稳妥,不会让最高位进一,所以应该不会溢出。

n = n ^ m;

m = n ^ m;

n = n ^ m;

方法三:(自己遇到的问题)

b = a + 0 * (a = b);

 

2-17 if

if else 结构 简写格式:变量 = (条件表达式)?表达式1:表达式2;

三元运算符:

好处:可以简化if else代码。

弊端:因为是一个运算符,所以运算玩必须要有一个结果

2-19 switch

case 穿透问题:switch 循环只在遇到两种情况结束:break , }。如果如果执行了一个case语句或default之后未到结尾的大括号,也没有遇到break,则会继续执行下面的语句,但不会判断case和default条件了,知道遇到break或右大括号,才会跳出循环。 循环中语句部分顺序,default语句可以放在任意处,但是先判断case语句。

switch 语句,只能判断byte/short/int/char类型,对于区间和boolean 类型无法判断,解决办法,可以先用数值代替区间或boolean 值。实际开发中,几种判断语句,根据情况选择最适合的。另外,5.0以后 可以判断枚举类型,7.0判断字符串。

一般判断的输值不多,属于byte/short/int/char类型用switch,区间或boolean类型用if语句。

3-1 while

Ctrl+c 强制停止命令运行,对dos 环境,比如遇到了while的打印死循环。

do{}while();循环语句后有分号;而while循环没有,如果不小心在while(); 后加了分号,编译不报错,系统会记入对while条件重复判断死循环中,而不执行后面大括号里循环体的内容。

3-4

如果变量只为控制循环变量,则用for 语句可是内存较为优化一点;若用while,则提前定义的循环变量在while循环结束后依然在内存中存在。

a.     变量有自己的作用域,对for 来将:如果控制循环的增量定义在for语句中,那么该变量只在for语句内有效,for执行完毕,该变量在内存中被释放。

b.     for 和 while可以进行互换,如果需要定义循环增量,用for语句更为合适(可优化内存);若想在循环后还要使用或打印出循环变的值,则用while合适或者for循环变量在for之前定义也可以。

3-8 for 嵌套

class Demo {

public static void main(String[] args) {

    

     for(int i=0;i<5;i++) {

         for(int y=i; y<5;y++) {

             System.out.print("*"); 

         }

         System.out.println();

     }

     /*

     尖朝上,可以改变条件,让条件随着外循环变化;

     尖朝下,可以改变初始值,让初始变量随外循环变化。

     */

    

     for(int i=0;i<5;i++) {

         for(int y=0; y<=i;y++) {

             System.out.print("*"); 

         }

         System.out.println();

     }

}

}

3-9

for 嵌套 舅舅乘法表

用制表符,比用空格好控制对其格式。

class Demo {

public static void main(String[] args) {

     for(int x=1; x<=9; x++) {

         for(inty=1; y<=x; y++) {

             System.out.print(y+"*"+x+"="+y*x+"\t");

         }

         System.out.println();

     }

}

}

03-10 break continue语句

break 用于switch选择结构和跳出循环;

continue 用于循环结构;

注释:

a)  注意break 和 continue 语句作用的范围。

a)       这两个语句单独存在时,下面 都不可以有语句,因为执行不到

b)       continue 是结束本次循环继续下次循环。

c)       标号的出现可以让这两个语句作用于指定的范围。

d)       可以在每个for循环结构前面带上一个标识符加冒号,如w: 以标识每一个循环结构,然后在break 或 continue后面可以写上 标识符,以指明是跳出那一层循环,若不写则默认自己所在循环。

3-11

打印复杂图形,可以将图形分解为简单模型,然后用嵌套循环分个实现。

3-12 函数概述

主函数由于是静态的,所以在调用其他函数时也只能调用静态的(常量)和方法,除非到后面学过对象后,可在main函数里new一个对象再用对象的引用调用相应的类的对象的方法。

函数里不可以定义函数,因为函数时平级的。

3-16

重载和方法返回值类型没有关系,只和参数的类型和个数有关。

3-17

int[] x = new int[3]; x是数组类型(三种引用类型的一种),x是数组名可以代表一个数组,其中的元素才是int 型的。

只有引用类型才能被赋值为null,比如上面的数组类型x. 可以写 x=null;代表x不再指向任何数组。

数组定义形式:第二种静态初始化: int[] a = newint[]{1,2,3}; 和 int[] a = {1,2,3};是相同的,后面是前面的简写。另外数组定一过元素个数后,是有初始化值的;数组下表[]越界,在编译时是不会报错的,因为编译只检查语法错误,只有在运行时才会报错。

报错信息:ArrayIndexOutOfBoundsException 越界异常

    NullPointerException 空指针异常,当引用没有任何指向,即引用值为空时,还在使用数组元素,就会报磁异常。比如把数组名赋值null,再去打印数组元素。

直接打印数组名,会打印出数组的引用,比如:[I@de6ced  分析。[ 代表数组;I 代表数组元素为int类型;@ 意思是at ,“地址在”的意思;de6ced 是16进制整数,代表该数组内存地址。

定义一个获取数组最值的方法,其中对变量max或min的初始化应该尽量赋值为数组中第一个元素再给数组中的每个元素作比较(最好把第一个元素的值赋给变量,这样在遍历数组进行比较的时候就可以从一开始循环,而不用和第一个作比较了);之所以不不初始化为零,还有一个原因,就是0放在数组中可能是最值。当让也可以初始化变量为零,让变量代表数组下标进行比较即可。

以升序为例子:

选择排序法:特点,第一轮比较完毕,最小值出现,

冒泡排序法:特点,每一轮比较完毕,最大值出现。

这两种方法,因为要频繁的在对内存中交换数值,所以速度比较慢;用希尔排序法才是最快的。但不需要掌握,因为类库中已经给提供了排序的算吧,直接调用就可以了。如果有人面试让你写个排序算法,你可以先引入后调用,import java.util.*; Arrays.sort(arr);就行了。

实际开发过程中就是用 Arrays.sort(array arr);方法的

4-7 数组折半查找法:两种方法(1)用mid 和要找数值的大小关系做循环条件 即while(key!=mid) (2)用序号做中间值,即while(min<max).

扩展应用:在有序数组中插入一个值,且插入后不影响数组的有序。求插入的位置。

先用折半查找法,查找一下数组中有没有和该数相同的数,若没有就返回循环跳出时min的值即是要找位置。

4-12 进制装换

4-14 二位数组定义:

int[][] y;  int y[][]; int[] y[]; 都可以;

定义两个数组: int[] x , y[];就是定义了一个一位数组x和一个二位数组y,但一般不要这样用。因为好多人都不认识。

5-7 面向对象 封装private

成员变量时在对内存中的,都以一个默认的初始化值。

临时变量都在栈内存中,必须先进行初始化才能继续使用。

5-9 构造代码块

构造代码块:定义在类中一对没有名字的大括号内。对象一建立就运行,而且优先于构造函数执行。

和构造函数的区别:构造代码块是给所有对象进行初始化,不论你new对象时调用的事哪个构造函数,该代码块都会被执行一次。而构造函数是给对应的对象初始化。

8-1 staic 

除了可以用对象名调用,也可以用类名调用。

6-5 帮助文档的制作

默认构造函数(就是自己没写)权限与类权限一致。

编写工具类说明书,API(应用程序接口)文档,用javadoc命令:

Javadoc _d 存储位置 –author –version文件名(比如:ArrayTool.java)

其中,_author _version 是想让生成的说明文档内容中显示作者和版本,可以不写。

但源文件中的工具类类必须是public 类。

类开头可以这样:

/**

对该类的说明,及该类提供了哪些方法

@author 作者名

@version 写上版本号(如:v1.1)

*/

在类中的一些说明文档,都可以写在

/**

 

*/之中。

/**

说明内容

@param 参数 对参数作用的说明

@return 对返回数据做出的说明

*/

 

6-6 静态代码块

类中形如staic{语句;} 就是静态代码块,随着类的加载而被执行,用于给类进行初始化;既然随着类加载,肯定其先于主函数执行,而且不论在类中的位置如何;若一个类中有多个静态代码块,则静态代码块之间按照出现的先后顺序被执行。

6-7 对象的初始化过程

Person p = new Person(“zhangsan”,20);

该句话都做了什么事情:

1.       因为new用到了Person.class,所以会先找到Person.class文件并加载到内存中。

2.       执行该类中的static 代码块,如果有的话,给Person.class进行初始化。

3.       在堆内存中开辟空间,分配内存地址。

4.       在对内存中建立对象的特有属性。并进行默认初始化。

5.       对属性进行显示初始化。(即在 类 中定义变量时写的初始化的值)

6.       对对象进行构造代码块初始化。

7.       对对象进行对应的构造函数初始化。(即构造函数中对对对象特有的元素进行赋值操作)

8.       执行除赋值外的其他语句;

9.       将内存地址赋给占内存中的P变量。

10.    另外,第4步之前应先执行本构造方法中调用的父类构造方法。

补充顺序的说明:类加载的过程:静态代码块随着类的加载而被执行,也就是说一旦加载上独立代码块就立即执行。故静态代码块中的语句只能访问写在它前面的静态成员,若访问后面的会编译报错。

测试程序如下:

程序一:

class Father

    {

           

           Father(){}

           

           Father(int age)

           {

                    System.out.println("fatherage:"+age);

           }

    }

   

class Son extendsFather

{

    static int i = 5;

    static {

        System.out.println("静态代码块"+i);

    }

    {

        System.out.println("构造代码块");

    }

   

        Son()

        {

                //默认这里有一个东西 super();

                //this(20);

               System.out.println("son");

        }

 

        Son(int age)

        {

                super(age);

                System.out.println("sonage:"+age);

        }

}

public class Test1 {

    public static void main(String[] args) {

        Son s = new Son();  //father;son

 

    Son s1 = new Son(20);//father;son age:20

    }

   

 

}

程序二:

class Person {

    int i = 5;

    int j;

    int k;

    {

        System.out.println("这是构造代码块"+i+j+k);

    }

    Person(int j, int k) {

        System.out.println("i="+i);

        System.out.println("j="+j);

        System.out.println("ceshiyuju");

        System.out.println("k="+k);

        this.k = k;

        System.out.println("k="+k);

        this.j = j;

   

    }

}

public class Test1 {

    public static void main(String[] args) {

        Person p = new Person(10,20);

    }

}

6-9 单例设计模式

有机会看本书:设计模式 次数有很多版本,讲述了一些常用的设计模式,是一种有效的设计思想,对某些问题行之有效的方法,GOF,可以简化你设计项目时的思路。

单例设计模式:解决一个类在内存只存在一个对象。

想要保证对象唯一。

1.       为了避免其他程序过多建立该对象,先禁止其他程序简历该类对象

2.       还为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象。

3.       为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。

这三部怎么用代码体现呢?

1.       将构造函数私有化。

2.       在类中创建一个本类对象。

3.       提供一个方法可以获取到该对象。

 

分饿汉式,懒汉式。开发一般用饿汉式,安全。因为懒汉式,若遇到几个程序同时调用它返回对象的函数时,可能同时产生数个对象,这和多线程知识有关。解决方式是,懒汉式加锁。但降低了执行效率,故实际开发时还是饿汉式好。

7-4 继承 父子中变量的特点

This 和 super指向的问题,没弄懂,有待看尚学堂视频。

已解决,不用看尚学堂了。

7-7 final关键字

内部类定义在类的局部位置上,只能访问该局部被final修饰的局部变量。

7-8抽象类

问:抽象类中可以有非抽象的方法吗?可以有。

抽象类不可以被实例化(不可以创建对象),其中有默认的构造方法么?类中有抽象方法,该类就是抽象类,类名之前就得写上abstract关键字?对的。抽象类可以从非抽象类继承吗?可以。

抽象类特点:

1.       抽象方法一定在抽象类中

2.       抽象方法和抽象类必须被abstract关键字修饰

3.       抽象类不可以用new创建对象。因为调用抽象方法没意义。

4.       抽象类中的抽象方法要被使用,必须有子类复写其所有的方法,建立子类对象调用;如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。

测试例子:

 

class S {

    public static void print() {

       

    }

}

 

abstract class Student extendsS {

    public static void print() {

        System.out.print("抽象方法");

    };

    void study() {

       

    };

}

 

class BaseStudent extendsStudent {

   

    void study() {

        System.out.println("BaseStudent study!");

    }

   

}

 

public class Test1 {

    public static void main(String[] args) {

        Student.print();

        BaseStudent s = new BaseStudent();

        s.study();

        s.print();

    }

}

测试结果:有抽象方法的类一定是抽象类,抽象类中可以没有抽象方法,可以有非抽象成员(成员变量和成员方法);抽象方法和抽象类都必须用abstract标识;抽象类中的非抽象静态方法可以用抽象类的类名直接调用。其非抽象非静态的方法因抽象类无法创建对象而无法调用,只能被子类继承或重写,并可由子类对象调用;抽象类同样可以继承非抽象类。

7-11 模板方法模式

在定义功能是,功能的一部分是确定的,但是有一部分是不确定,而确定的部分在使用不确定的部分,那么这时就将不确定的部分暴漏出去,由该类的子类去完成。

提高了拓展性和复用性。

7-12 接口

接口是不可以创建对象的,因为有抽象方法。

需要被子类实现,子类对接口中的方法全部实现后,子类才可以实例化,否则子类是一个抽象类

接口定义时格式如下:

1.       接口中常见定义:常量,抽象方法。

2.       接口中的成员都有固定修饰符。

a)       常量:publicstatic final

b)       方法:publicabstract

c)       这些固定修饰符可以不写,系统会默认存在,但建议写上。

d)       记住:接口中的成员都是public的

 Java支持多继承,但只有在接口之间存在:接口A可以同时继承B、C。

类之间,接口之间用继承extends;类和接口之间用实现implements。所以类之间是单继承,但接口之间是可以多继承 的。Java中的多继承用多实现implements替代的;但多继承依然无法避免继承的方法名重发但返回值类型不同的弊端,所以,当我们编写接口或继承接口的时候应尽量避免这样的继承或实现。

7-15 接口举例

降低了程序的耦合度,接口是一种拓展功能。

一个类的必备功能可以定义在父类中,而拓展功能应该定义在接口中。

如学生的学习方法就可以定义在父类中(抽象不抽象都可以),而抽烟可以定义在接口中,由会抽烟的学生类实现。(简单了解下,可以不必在意)

8-5 多态中成员的特点

(1)在多态中成员函数的特点:

在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。

在运行时期:参阅对象所属的类中是否有个调用的方法。

简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。

也就是说,父类的引用指向子类时,只能调用子类中父类定义的方法,如果方法被子类重写则调用子类的重写方法,若没重写则调用从父类继承的方法。

(2)在多态中,成员变量的特点:

无论编译和运行,都参考左边(引用型变量所属的类)。(引用型是等号左边声明的变量,被引用型是等号右边实际传递的对象所属的类型)

如父类和子类中都定义了num成员变量,那么 Fu f = new Zi(); f.num调用的就是父类中的num; Zi z = new Zi(); Z.num调用的就是子类中的num;

(3)在多态中,静态成员函数的特点:

无论编译和运行,都参考左边。

如果父类和子类中定义了重名的静态方法,则父类的静态方法并没有被子类的静态重名方法覆盖,如果用父类的引用指向子类对象,那么用父类引用调用该方法,就是调用了父类的静态方法;只有子类的引用才会调用子类的静态方法。那么 Fu f = new Zi(); f.method()调用的就是父类中的method(); Zi z = new Zi(); Z.method()调用的就是子类中的method();

原因是:静态方法是静态绑定的,随着类的加载静态方法被加载到内存中时就已经绑定了该类的引用。而非静态方法时动态绑定的,只有在执行时,引用指向的实际对象是谁方法就对谁绑定。

静态的成员是属于类的,不属于某个对象,所以静态成员不会随着实际传递的对象不同而改变,也就是不会动态绑定给某个对象,就不存在多态。

 

 

9-1内部类访问规则:

内部类的访问规则:

1.       内部类可以直接访问外部类的成员,包括私有。

a)       之所以可以直接访问外部类中的成员,是因为内部类中持有了外部类的引用,格式是外部类名.this

b)       如果外部类,内部类,内部类的方法内都有一个成员变量num,那么在该方法内只写num,访问的是最近的也就是方法内部定义的num;如果想访问用this.num是访问内部类的num;用Outer.this.num是访问外部类的num;如果内部类和内部类方法中都没有重名变量num,则只需写一个num即默认访问外部类的num.

2.       外部类要访问内部类,必须建立内部类对象。

内部类可以被私有格式,其前加 private修饰,当内部类在外部类的成员位置上时。

其他类放问一个类的内部类,也要new一个该内部类对象,但要用全名,即外部类.内部类 比如: Outer.Inner in = new Outer().newInner();等号后面是先new了一个外部类对象,在用外部类对象调用内部类。

访问格式:

1.       当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中,可以直接建立内部类对象。

a)       格式

                                  i.             外部类名.内部类名 变量名 = 外部类对象.内部类对象;

                               ii.             Outer.Inner in = new Outer().new Inner();

 

9-2 静态内部类

2.       当内部类在成员位置上,就可以被成员修饰符所修饰。比如,

a)       private:将内部类在外部类中进行封装。

b)       static :内部类就具有static的特性。

c)       当内部类被static修饰后,只能直接访问外部类中的static成员,出现了访问局限。

d)       在外部其他类中,如何直接访问static内部类的非静态成员呢?用: newOuter.Inner().function();

e)       在外部其他类中,如何直接访问static内部类的静态成员呢? Outer.Inner.function();

注意:当内部类中定义了静态成员,该内部类必须是static的。

当外部类中的静态方法访问内部类时,内部类也必须是static的。

    9-3 内部类定义原则:

当描述事物时,事物的内部还有事物,该事物用内部类来描述。

因为内部类事物在使用外部事物的内容。

9-4 匿名内部类

内部类定义在局部时,

1.       不可以被成员修饰符修饰

2.       可以直接访问外部类中的成员,因为还持有外部类中的引用。但是不可以访问它所在的局部(一般为方法)中的变量,只能访问被final修饰的局部变量。

匿名内部类:

1.       匿名内部类其实就是内部类的简写形式。

2.       定义匿名内部类的前提:内部类必须是继承一个类或者实现接口。

3.       匿名内部类的格式: new父类或者接口(){第一子类的内容};

4.       其实匿名内部类就是一个匿名子类对象。

5.       可以将匿名内部类传递给一个父类引用,并用该父类引用调用类中方法(实现的父类方法,当然也可以定义子类特有的其他方法,但用匿名内部类的目的就是为了简化代码,若再在其中添加其他的方法,而父类引用又无法调用该方法,只能通过重写一次该匿名内部类对象来调用,也就失去了原来省事的目的了;所以匿名内部类内部只要实现父类或借口的方法就可以了,不要再定义自己的方法了)。但一般不用。

6.       匿名内部类中的方法最好不要超过三个。这样看起来简洁,否则就失去了她原来的目的了

7.       父类或被实现的接口内的方法过多的话,一般用个类继承并实现,让后创建个该类对象来调用;如果方法过少或只有一个,即直接用匿名内部类比较简洁。

8.       内部类时为简化书写而存在的,如果里面内容过多就失去使用它的意义了

9.       如果想写一个内部类,又没有父类时,可以用Object作为其父类。

9-5异常

常见异常:

9-7

    在函数上声明异常。便于提高安全性,让调用处进行处理,不处理编译失败。

若没有声明异常,也没有主动捕获异常,则最后会由虚拟机捕获并做默认处理,之后会直接终止程序的执行;若自己主动捕获并做了处理,则虚拟机就没有机会做处理了,主动处理后,处理语句后面的程序语句继续执行。

9-8

多异常处理 

1.       声明异常时,建议声明更为具体的异常。这样处理的可以更具体。

2.       对方声明几个异常,就对应有几个catch块。(不要定义多余的catch块,这样如果出项了没有提前预测到的异常,程序就会停止,我么就可以知道了)如果多个catch块中 的异常出现继承关系,父类异常catch快放在最下面。

3.       建议在进行异常处理时,catch中一定要第一具体处理方式。不要简单定义一句e.printStacktrace(),也不要简单地写一条输出语句。方法之一:将异常输出到异常记录文件。

9-9 自定义异常

因为项目中会出现特有的问题,而这些问题并未被java所描述并并封装对象。所以对这些特有的问题可以按照java的对问题封装的思想将特有的问题进行自定义封装。

自定义的异常(类)要从异常父类继承,比如Exception;,定义好异常类后,在可能出现该异常的地方做出判断并抛出该类异常对象,比如:if(b<0) throw new FuShuException();并在该函数上声明(用throws)(因为,一般情况在函数内部出项异常,函数上要声明,以提醒调用它的函数做出相应处理或继续抛出)

当在函数内部出现了throw抛出异常对象,那么就必须要给出对应的处理,要么在内部用try catch处理,要么在函数上声明让调用者处理。

因为自定义的异常并未定义信息,故打印结果只有异常名称,

那么如何定义异常信息呢?

自定义异常,必须是自定义类继承Exception.

例如:

class FuShuException extends Exception {

    FuShuException(String[]msg) {

        super(msg);

    }

}

当然,该自定义类中还具有了从父类继承的getMessage()等方法。

 

 

9-11      RuntimeException

Exception有一个特殊的子类异常RuntimeException运行时异常。

如果在函数内用throw抛出该异常,函数上可以不用声明,编译一样通过。如果在函数上声明了该异常,调用者可以不用进行处理(用try catch语句或在函数上 抛出),编译一样通过。

自定义异常时,如果该异常的发生无法继续进行运算,就让自定义异常继承RuntimeException.

对于异常分两种:

1.编译时被检测的异常

2.编译时不被检测的异常(运行时异常,RuntimeException以及其子类)

10-1 异常 finally

养成良好的编程习惯:

Try catch 语句后面一定要跟finally语句,强制执行一些关掉资源的语句,这是一个良好的变成习惯。

Finally里的语句一定会被执行,即使前面的catch里有return,但如果有System.exit(0)语句finally语句就无法继续执行了。{ 另外接受一种属于自己的异常可以返回一种别人能处理的异常。}

10-2 异常处理语句其他格式

try catch

try catch finally

try finally:记住一点,catch 是用于处理异常。如果没有catch就代表异常没有被处理过,如果该异常是检测时异常,那么必须声明(throws)。

当然,try后面可以跟多个catch语句。

10-3异常覆盖时的特点

异常在子类覆盖中的体现:

1.       子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法只能抛出父类飞异常或该异常的子类。若子类覆盖方法却是存在其他异常,则必须在自己方法内用try catch自行处理

2.       如果父类方法抛出多个异常,那么子类覆盖方法是稚嫩抛出父类异常的子集。

3.       如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法是,也不可以抛出异常。如果子类方法发生率异常,就必须进行try处理,绝对不能抛。

4.       总之,就是保证子类抛出的异常能被处理父类方法异常的语句处理。

以后写代码过程中经常会遇到问题,应该写异常对象来解决。

10-5 面向对象 异常总结

视频上有对异常所有知识点的总结,一定要看。完全可以替代笔记。

 

Throw语句单独存在时,下面不要定义语句,因为执行不到,会编译报错。

10-7 pacage

-d参数,指定文件编译后存放的目录(连同生成的包一块,自定建立类中代码写的包)

javac -d . 文件名.class 把文件编译后存放在当前目录下

javac –d 路径 文件名.class 把文件编译成class后(把自动生成的包)存放到指定路径(把生成的类自动放入包中)

java执行文件时要写class文件的全名 即包名.类名

用import引入不同包中的很多类时,一定要注意不能有重名的类,否则,必须考写全包名来避免。

课程外小知识:return用法疑难点:

凡是有返回值类型的函数,都要有绝对能被执行到的return语句;一般在函数体中直接写上return 语句;

如果return语句只写在了循环体中,函数体内没有直接的return语句,那么只有一种情况是合法的,就是定义true循环。

所谓true循环就是while(true),for(;true;),for(;;),也就是判断语句只能为常量true,不能传递任何变量,即使定义了变量值为true也不行。但是如果这样定义是可以的,final boolean i = true;while(i)是可以的,因为 i 是个常量true. 对于我的解答你可以无限测试。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值