javaSE笔记2

文章详细介绍了Java中的Object类,包括其常用方法和finalize()方法。讨论了内部类的种类、声明与实例化。讲解了数组的特性、初始化方式以及多维数组。深入探讨了String类,强调了字符串的不可变性和字符串常量池。此外,还提到了异常处理机制,包括编译时异常和运行时异常的区别,以及如何通过try-catch-finally处理异常。
摘要由CSDN通过智能技术生成

Object类
1、常用方法:
    protected Object clone();//负责对象克隆的方法,只能在本类方法中克隆本类的对象。
    int hashCode();//获取对象哈希值的一个方法
    boolean equals();//判断两个对象是否相等
    String toString();//将对象转换成字符串形式
    protected void finalize();//垃圾回收器负责调用的方法
2、Java中基本数据类型可以使用“==”比较相等。
   Java中所有引用数据类型统一使用equals方法来判断是否相等。
3、引用数据类型中只有String类型比较特殊可以使用“String str = "HelloWorld!"”,不用通过new的方式就直接可以创建对象,使用这种方式创建出来的字符串对象在字符串常量池中存储,并且可以使用“==”来判断相等。
4、当一个Java对象即将被垃圾回收器回收的时候,垃圾回收器负责调用finalize()方法,这个方法不需要程序员手动调用,是JVM负责调用的。【类似静态代码块,finalize()方法也是SUN公司为Java程序员准备的一个时机,垃圾销毁时机】
5、finalize()方法只需要重写不需要程序员手动调用,是GC机制负责调用的[但是程序员是可以手动调用的]。【某个类重写了finalize()方法,某个类型的对象被垃圾回收器回收的时候,GC负责调用finalize()方法】
6、Java中的垃圾回收器不是轻易启动的,垃圾太少、或者时间没到,种种条件下,有可能启动,也有可能不启动。
7、System.gc();建议启动垃圾回收器
8、hashCode()方法返回值是哈希码:
   实际上就是一个Java对象的内存地址,经过哈希算法得出的一个值。所以hashCode()方法执行结果可以等同看作是一个Java对象的内存地址。

内部类
1、在类的内部有定义了一个新的类,被称为“内部类”;
2、内部类的分类:
    静态内部类:类似于静态变量【实例化方式:“new 外部类.内部类()”】
    实力内部类:类似于实例变量【实例化方式:“new 外部类().new 内部类()”】
    局部内部类:类似于局部变量【只能在方法体内部实例化:“new 内部类()”】,方法执行结束之后类就消失了所以局部内部类不能使用static修饰,也不能使用private修饰
        匿名内部类属于局部内部类的一种。
3、代码:
class Test {
    //该类在类的内部所以称为内部类
    //由于前面有static所以称为“静态内部类”
    static class Inner1 {}
    //没有static修饰的类叫做实例内部类
    class Inner2{}
    public void doSome () {
        //在方法里面定义的类,叫做局部内部类
        class Inner3 {}
    }
}
4、内部类里面还可以有内部类,无限套娃,但是可读性从差。
5、实例内部类和静态内部类生成的class字节码文件名是:“外部类名$内部类名....class”
   局部内部类生成的class字节码文件名为:“外部类名${从1开始递增的序号}内部类名.class”【“从1开始递增的序号”用来解决局部内部类同名的问题,如果局部内部类同名则按照在外部类中出现的先后顺序序号依次递增】
   匿名内部类生成的字节码文件命名“外部类${从1开始递增的序号}.class”;【“从1开始递增的序号”按照匿名内部类在外部类中出现的顺序依次递增】
6、匿名内部类要以分号“;”结束。
7、类只定义不创建对象是没有任何意义的。就是无效类。内部类也是一样的道理。
   类在使用到的时候的时候动态加载【也就是“new对象”的时候】。内部类也是一样的道理。
   匿名内部类是在执行到的时候立马就加载了。
8、因为匿名内部类没有名字,所以只能使用一次。
9、内部类的类型怎么表示?
    外部类名.内部类名;
    外部类名.内部接口名;
10、类中可以定义内部接口,接口中也可以定义内部类。


数组
1、Java语言中的数组是一种引用数据类型,不属于基本数据类型。数组的父类是Object。
2、数组是一个容器,可以容纳多个元素。(数组是一个数据的集合)
3、数组当中可以存储“基本数据类型”,也可以存储引用类型的数据。
4、数组是引用类型,所以数组对象是堆内存当中。
5、数组当中如果存储的是“Java对象”的话,实际上存储的是对象的“引用(内存地址)”,数组中不能直接存储java对象。
6、数组一旦创建,在Java中规定,长度不可变。(数组长度不可变)
7、数组的分类:一维数组、二维数组....
8、所有的数组对象都有length属性(java自带的),用来获取数组中元素个数。length是属性不是方法,不用带小括号。
9、Java中的数组,要求数组中的元素类型统一。比如:int类型的数组只能存储int类型的数据。
10、数组中的元素内存地址是连续的。(存储的内一个元素都是有规律的挨着排列的)
11、数组实际上是一种简单的数据结构。
12、java中只有数组和String可以不适用new也可以创建对象。(String s = "xyh";int[] array = {1,2,3,4,5})。
    即使是采用“int[] array = {1,2,3,4,5}”这种方式创建的数组对象,底层Java编译器编译的时候也会转换成int[] array = new int[]{1,2,3,4,5};这样的形式;多维数组也是这样
13、数组中首元素的内存地址,作为整个数组元素的内存地址。
14、数组中每个元素都有下标,下标从0开始,以1递增,最后一个元素的下标是:“length - 1”。
    下标很重要,对数组进行“存取”的时候都是通过下标来进行的。
15、数组这种数据结构的优缺点?
    优点:查询/查找/检索某个下标上的元素效率极高。可以说是查询效率最高的一种数据结构。
        为什么检索效率高?
            第一:每个元素的内存地址在空间上是连续的。
            第二:每一个元素类型相同,所以占用空间大小一样。
            第三:知道第一个元素的内存地址,知道每个元素占用空间的大小,又知道下标,所以通过一个数学表达式就可以计算出某个下标上的元素的内存地址,直接通过内存地址定位到元素,所以数组的检索效率几乎是最高的。
    缺点:
        第一:为了保证数组中每个元素的内存地址是连续的,所以在数组上随机增删元素的时候,效率较低,因为随即增删元素会涉及到后面的元素统一向前或者向后位移的操作。
        第二:数组不能存储大数据量:因为很难在内存空间上找到一块特别大的连续的内存空间。
16、怎么声明一个一维数组?
    语法格式:
        数据类型 [] 数组名;
        int [] array1;
        Object[] array2;
17、怎么初始化一个一维数组呐?
    包括两种方式:静态初始化一维数组,动态初始化一维数组。
    静态初始化语法格式:
        省略写法:即使使用的是省略写法,编译的时候编译器也会将此代码转换成完整写法。
        数据类型[] 数组名 = {数据1,数据2,数据3...};
        int[] array = {100,2100,300,55};
        完整写法:
        数据类型[] 数组名 = new 数据类型[]{数据1,数据2,数据3...};
        int[] array = new int[]{100,2100,300,55};
    动态初始化语法格式:
        数据类型[] 数组名 = new 数据类型[长度];//java中只有数组对象new的时候后面是“中括号”,后面中括号中的“长度”只能是int类型的(或者可以自动转换成int类型的数据),不能是long类型的
        //后面中括号中的长度可以是int类型的变量,在C语言中就不可以,但是可能会抛出java.lang.OutOfMemoryError内存不足错误。
        int[] array = new int[5];//默认是各个基本数据类型的默认值
        String[] names = new String[6];//引用数据类型的数组默认值是null 
18、当你创建数组时,确定数组中存储那些具体元素时,采用静态初始化方式。
    当创建数组时,不确定数组中存储那些数据,可以采用动态初始化的方式,预先分配内存空间。
19、方法是“m(String[] arr)”的时候,不能采用静态初始化的方式直接传递实参,“m({"123","456"});//这样是错误的”,但是可以采用“m(new String[]{"123","456"});”的方式传递实参”
20、main方法的参数是“(String[] arr)”,JVM负责调用的,所以JVM调用的时候一定会给main方法传递一个String类型的数组。我们没有手动给出参数的时候,JVM会给一个长度为0的String类型的数组。
21、main方法上的“String[] args”主要是用来接收用户输入的参数。例如:“java Test abc def”,这里的abc fef就会被转换成String[] args数组。
22、设置“数组名[下标] = 数据”,获取“数组名[下标]”。【“数组名[下标]”代表数组中“下标这个位置的值”】
23、多态数组:父类型的数组可以存储子类型对象(引用)。
    比如:Animal[] animals = new Animal[]{new Cat(),new Brid()};
    只要存储的类型与数组的类型兼容就可以。
24、数组扩容
    先新建一个大容量的数组,然后将小容量数组中的数据一个一个拷贝到大容量数组中。
    结论:数据扩容效率较低。因为涉及到拷贝问题。所以在以后开发中请注意:尽可能少的进行数组的拷贝。可以在创建数组对象的时候预先估计一下多长合适,最好估算准确,这样可以减少数组的扩容次数。提高效率。
25、数组拷贝函数:System.arraycopy(src,src下标,dest,dest下标,拷贝长度);【可能会抛出数组下标越界异常】
    对于基本数据类型:源和目标只能是相同类型的,对于引用数据类型目标可以是源的父类型。
26、对于基本数据类型,数组的类型和数组中数据的类型只能相同,因为数组中“每一个元素类型相同,所以占用空间大小一样”
    对于引用数据类型,数组可以是父类型的数组,数组中存储的引用可以是子类型的引用。

二维数组
1、二维数组其实是一个特殊的一维数组,特殊在这个一维数组当中的每一个元素又是一个一维数组。
2、二维数组也是有两种初始化的方式:
    静态初始化语法结构:
        简化写法:
        数据类型[][] 数组名 = {{数据1,数据2,数据3....},{数据1,数据2,数据3....},{数据1,数据2,数据3....}....};
        int[][] array = {{12,3,2,3,23},{1,2,3},{12}};
        完整写法:
        数据类型[][] 数组名 = new 数据类型[][]{{数据1,数据2,数据3....},{数据1,数据2,数据3....},{数据1,数据2,数据3....}....};
        int[][] array = new int[][]{{12,3,2,3,23},{1,2,3},{12}};
    动态初始化语法结构:
        数据类型[][] 数组名 = new 数据类型[长度1][长度2];
        int[][] array = new int[10][20];//定义了一个十行二十列的二维数组
        int[][] array = new int[10][];//距离数据类型最近那个长度不能省略,其他的都可以省略
        最后的中括号中从左往右开始,至少有一个长度值,后面可以空白,但是中间不能跳跃。
3、数组赋值:
    代码片段:
    int[][] array = new int[][]{{12,3,2,3,23},{1,2,3},{12}};
    int[] a;
    //a = {12,3,2,3,23}; 错误:只有在声明的时候赋值才可以省略new
    a = new int[]{12,32,4,56,12}; //语法通过
    a = array[0]; //语法通过,但是这样a与array[0]指向是相同的内存空间“因为array[0]是一个一维数组的内存地址,并且a是一个一维数字的变量,可以把array[0]地址,赋值给a变量”
4、比如:int[][] array = new int[][]{{12,3,2,3,23},{1,2,3},{12}};“array.length”就是二位数组的长度,结果是3
   比如:int[][] array = new int[][]{{12,3,2,3,23},{1,2,3},{12}};“array[0].length”就是二位数组中的第一个一维数组的长度,结果是5
5、n维数组就有n个中括号“[]”。int[][][]... n个中括号。
6、若想返回多个值,返回值类型可以是一个数组。
    public int[] m (){return new int[]{1,2,3,4,5,6}};

Arrays工具类(java.util.Arrays)
1、“Arrays.sort(实参);”该方法用于数组排序。
2、排序算法
    冒泡排序
    选择排序
   查找算法
    二分查找
        建立在排序的基础上
3、“Arrays.binarySearch(数组,从数组中查找的值);”,二分查找方法,若元素存在返回元素在数组中的位置,若不存在则返回“-1”。

String类(java.lang.String)
1、String表示字符串类型,属于引用数据类型,不属于基本数据类型。
2、java中随便用双引号括起来的都是String对象。
3、java中规定双引号括起来的字符串是不可变的,从出生到死亡都是不可变的“"abc"不能变成"abcd"”。
4、在java中双引号括起来的字符串,例如:"abc"都是直接存储在“方法区”的“字符串常量池”当中的。【“字符串常量池”顾名思义“常量”是不可变的】。
   为什么SUN公司把字符串 存储在字符串常量池当中呐?因为字符串在实际开发中使用太频繁了。为了执行效率,所以把直接用双引号括起来的字符串放到了字符串常量池当中。
5、new对象的时候一定是在堆内存中开辟空间的,凡是用双引号括起来的都在字符串常量池当中有一份。(String str = new String("xyh"));其中的"xyh"就在字符串常量池中有一份。
6、String类型的引用中同样是保存了对象的内存地址。
7、垃圾回收器不会释放常量池当中的常量。
8、“==”比较的是变量中保存的那个东西。
9、基本数据类型变量中都是直接保存值,引用数据类型变量中都是保存内存地址。
10、常用构造方法:
    String(byte[] bytes)
    String(byte[] bytes,int offset,int length);//offset起始下标,length长度
    String(char[] chars)
    String(char[] chars,int offset,int length);//offset起始下标,length长度
11、常用的创建字符串的方式:
    String s = "";//最常用
    String s = new String("");//""里面的东西在字符串常量池当中有一份,因为有new所以在堆内存当中有一个String对象,s指向堆内存中的String对象,堆内存中的对象保存字符串常量池当中的""的内存地址
    String s = new String(byte数组);
    String s = new String(byte数组,起始下标,长度);
    String s = new String(char数组);
    String s = new String(char数组,起始下标,长度);
12、String常用方法
    1.char charAt(int index);//返回当前字符串中index下标的字符(字符串中的下标从0开始)
    2.int compareTo(String anOtherString);//按照字典的顺序比较字符串,字符串比较不能直接使用“>,<”。【“前减后”,能分胜负直接返回,不往后比较,不能分胜负接着比较后面的】
    3.boolean contains(CharSequence s);//判断当前字符串中是否包含“s”字串
    4.boolean endsWith(String suffix);//判断当前字符串是否以某个字符串结尾。“suffix”是后缀的意思
    5.boolean startsWith(String prefix);//判断当前字符串是否以某个字符串开始。“prefix”是前缀的意思
    6.boolean equals(Object anObject);//判断两个字符串是否相等 
    7.boolean equalsIgnoreCase(String anOtherString);//忽略大小写比较字符串是否相等
    8.byte[] getBytes();//将字符串转换成一个byte数组
    9.int indexOf(String str);//返回某个字串在当前字符串中第一次出现的索引。
      int indexOf(String str,int fromIndex);//返回某个字串在当前字符串中第一次出现的索引,从指定索引开始
    10.int lastIndexOf(String str);//返回某个字符串在当前字符串中最后一次出现的索引。
       int lastIndexOf(String str,int fromIndex);//返回某个字符串在当前字符串中最后一次出现的索引。
    11.boolean isEmpty();//判断某个字符串是否为空“""”,空串
    12.int length();//获取当前字符串的长度。
       判断字符串的长度使用length()方法;判断数组的长度使用length属性。
    13.replace(char oldChar,char newChar); //通过newChar字符替换当前字符串中出现的所有oldChar,返回一个新的字符串
       replace(CharSequence target,CharSequence replacement);//将当前字符串中的所有target字符换替换成replacement字符串,返回一个新的字符串
       replaceAll(String regex,String replacement);//与replace不同的是本函数支持正则表达式
       replaceFirst(String reges,String replacement);//用replacement字符串替换当前字符串中与regex匹配的第一个字串
    14.String[] split(String regex);//通过与regex匹配的字符串进行拆分
       String[] split(String regex,int limit);//通过与regex匹配的字符串进行拆分,最多拆分成limit个字串,“limit”是限制的意思
    15.String substring(int beginIndex);//从下标为beginIndex的位置开始截取,到当前字符串的结尾
       String substring(int beginIndex,int endIndex);从下标为beginIndex的位置开始截取,到下标为endIndex的位置,截取的子串中不包括下标为endIndex的字符
    16.char[] toCharArray();//将字符串转换成char数组
    17.String toLowerCase();//将当前字符串复制一份,然后将复制之后的字符串中的字母全部转换成小写(不是在原字符串上更改)
    18.String toUpperCase();//将当前字符串复制一份,然后将复制之后的字符串中的字母全部转换成大写(不是在原字符串上更改)
    19.String trim();//去除字符串前后空白
    20.String中只有一个方法是静态的,不需要new对象,这个方法是:String valueOf(实参)
       作用:将“非字符串”转换成“字符串”
       语法结构:“String.valueOf(实参)”
       这个静态的valueOf方法,参数是一个对象的时候,会自动调用该对象的toString方法,将该对象转换成字符串表示形式。
13、本质上System.out.println()这个方法在输出任何数据的时候,都是先转换成字符串,再输出。

StringBuffer类(java.lang.StringBuffer)
1、我们在实际开发中,如果需要进行字符串的频繁拼接,会有什么问题?
   因为java中的字符串是不可变的,每一次拼接都会产生新字符串。这样会占用大量的方法区内存。造成内存空间的浪费。
   比如:String s = "abc";s += hello;//就这量条语句就在常量池中创建了3个对象。这样会给java的方法区中的字符串常量池带来很大的压力。
   如果以后需要进行大量字符串拼接操作,建议使用JDK中自带的:
   java.lang.StringBuffer;
   java.lang.StringBuilder;
2、构造方法:
    StringBuffer();构造一个不带字符的字符串缓冲区,初始容量为16
    StringBuffer(CharSequence seq);构造一个字符串缓冲区对象,它包含指定seq相同的字符序列。
    StringBuffer(int capacity);构造一个不带字符串,具有初始容量的字符串缓冲区对象。
    StringBuffer(String str);构造一个字符串缓冲区,将其内容初始化为指定的字符串内容。
3、StringBuffer的性能优化?在创建StringBuffer的时候尽可能给定一个初始化容量。最好减少底层数组扩容次数。与估计一下,给一个恰当的初始化容量。
4、StringBuffer是线程安全的。【方法都有synchronized修饰】
   StringBuilder是非线程安全的。
5、扩容机制:底层调用“ensureCapacityInternal”方法确保容量。当容量不足的时候,创建一个容量更大的数组,采用“System.arraycopy”函数进行对存储字符串中的字符数组拷贝扩容。

包装类
1、java中为8种基本数据类型又对应提供了8种包装类型。8种包装类型属于引用数据类型,父类是Object。
2、基本数据类型             包装类型
-----------------------------------------------------------------------------------------------------------
      byte                    java.lang.Byte(父类java.lang.Number)
      short                    java.lang.Short(父类java.lang.Number)
      int                    java.lang.Integer(父类java.lang.Number)
      long                    java.lang.Long(父类java.lang.Number)
      float                    java.lang.Float(父类java.lang.Number)
      double                java.lang.Double(父类java.lang.Number)
      boolean                java.lang.Boolean(父类java.lang.Object)
      char                    java.lang.Character(父类java.lang.Object)
3、八种包装类种其中6种都是数字对应的包装类,他们的父类是java.lang.Number
   java.lang.Number是抽象类
4、//基本数据类型-(转换为)->引用数据类型:称为“装箱”
   Integer i = new Integer(10);//10这个基本数据类型,进行构造方法的包装达到了:基本数据类型向引用数据类型的转换。
   //引用数据类型转换为基本数据类型:称为“拆箱”
   int retValue = i.intValue();//“i”这个引用数据类型转换为“10”这个基本数据类型
5、java.lang.Number有很多抽象方法:(这些方法都是负责拆箱用的)
    1.byteValue()
    2.doubleValue()
    3.floatValue()
    4.intValue()
    5.longValue()
    6.shortValue()
6、包装类的构造方法:
    int:    
        Integer(int value);
        Integer(String s);//如果给定的s不是一个纯数组字符串会抛出NumberFormatException异常
    boolean:
        Boolean(boolean value);
        Boolean(String s);//如果给定的s不是一个纯布尔型字符串,不会抛出异常,会被转换为“fasle”,只有“"true"”是真
    byte、short、long、float、double构造方法以此类推,都是有两个构造方法,一个当前类型的一个String类型的
    char:
        Character(char c);//char的包装类只有一个构造方法
7、各个包装类的常量:
    Integer.MAX_VALUE--->int类型的最大值
    Integer.MIN_VALUE--->int类型的最小值
    Integer.TYPE--->int
    以此为例,其他类型以此类推
8、JDK1.5之后java支持自动装箱、自动拆箱,Number类的方法就用不到了。
    //自动装箱
    Integer x = 100;//相当于手动装箱Integer x = new Integer(100);因为x是Integer类型的变量,需要一个Integer类型的数据,所以java会自动将基本数据类型的100转换成Integer类型的对象赋值给x。
    //自动拆箱
    int y = x;//相当于手动拆箱int y = x.intValue();java会把x包装的整数赋值给int类型的变量。
    //在程序需要进行装箱的时候自动装箱,在需要进行拆箱的时候就自动拆箱。
    Integer z = 1000;System.out.println(z + 1);//z会自动转换成基本数据类型
    //其他类型装箱和拆箱以此类推
9、代码:
        Integer a = 127;
        Integer b = 127;
        System.out.println(a == b);//true,直接从整数型常量池当中取出来的包装对象
        Integer a1 = 128;
        Integer b1 = 128;
        System.out.println(a1 == b1);//false
        Integer a2 = new Integer(127);
        Integer b2 = new Integer(127);
        System.out.println(a2 == b2);//false,还会再堆内存中创建对象
    java中为了提高程序的执行效率,将[-128~127]之间的数据所有类型(int、byte...)的包装对象提前创建好,因为这个区间的数据包装对象太常用了,放到方法区内存当中的“整数型常量池”当中了,目的是只要用到这个区间的数据的包装对象,不需要再new了【前提是使用“自动装箱”机制,自己new的还是会再堆内存中创建对象】,直接从整数型常量池中取出来。
10、池:就是缓存机制(cache)。优点:效率高。缺点:耗费内存。
    大型项目中的重要优化手段就是cache缓存机制。
11、Integer常用方法:    
    1.static int parseInt(String s);//将String -(转换为)->int,Double类型的有parseDouble(String),将String转换成Double,其他各个类型以此类推,可能会抛出NumberFormatException异常
    2.static String toBinaryString(int i);//将i转换成二进制的字符串表示形式
      static String toHexString(int i);//将i转换成十六进制的字符串表示形式
      static String toOctalString(int i);//将i转换成八进制的字符串表示形式
    3.static Integer valueOf(int i);//int--(转换成)-->Integer;装箱
      static Integer valueOf(String s);//String--(转换成)-->Integer;可能会抛出NumberFormatException异常

java中日期的处理(java.util.Date)
1、java.util.Date;是SUN为java程序员提供的处理日期时间的类。
2、java.text.SimpleDateFormat;是专门用来格式化日期的类。
    使用构造方法规定日期的格式:public SimpleDateFormat(String pattern);
    调用SimpleDateFormat类对象的String format(Date date);方法返回格式化之后的日期字符串对象
    还可以通过调用SimpleDateFormat类的parse(String stringDate)方法,返回一个Date对象,stringDate的格式必须与SimpleDateFormat对象规定的日期格式相同,否则会抛出异常ParseException.    
3、怎样获取系统当前时间?
   获取自1970年1月1日 00:00:00 000到当前系统时间的总毫秒数
   System.currentTimeMillis();
4、java.util.Date;的构造方法
   public Date();//无参构造方法,使用该方法创建的是当前的时间的Date对象
   public Date(long date);//date是距离1970年1月1日 00:00:00 000时间的毫秒数
   //当date是0的时候,创建的时间就是1970年1月1日 00:00:00 000

数字格式化(java.text.DecimalFormat)
1、java.text.DecimalFormat专门用于数字格式化的。
2、构造方法:public DecimalFormat(String pattern);//pattern规定的时格式化之后的数组的显示格式
   比如:DecimalFormat df = new DecimalFormat(",###.###");//“.”之前不管有几位数字,每3位之间一个逗号,“.”之后的是小数。
   ,:表示千分位
   .:表示小数点
   0:不够用0补齐

大数据(java.math.BigDecimal)
1、经常用于“财务”软件中。
2、BigDecimal属于大数据,精度极高。不属于基本数据类型,属于java对象(引用数据类型)。
3、父类都是java.lang.Number.
4、加减乘除方法:
    加:add()
    减:subtract()
    乘:multiply()
    除:divide()
5、类似的大整数类:java.math.BigInteger;

随机数(java.util.Random)
1、Random用于产生随机数。
2、构造方法:
    Random():无参构造方法
    Random(long seed):第一次产生的随机数是随机的,但是同一个类型的数据以后每次都是调用都是这次产生的这个值了。
3、常用方法:    
    1.int nextInt();//返回一个int类型int范围内的随机数
      int nextInt(int bound);//返回一个[0~bound-1]范围内的int类型的随机数
    2.double nextDouble();//返回一个double类型double范围内的随机数
      int nextDouble(double bound);//返回一个[0.0~bound-1]范围内的doulbe类型的随机数

枚举类型
1、枚举:i一枚一枚可以列举出来的,才建议使用枚举类型。
   枚举编译之后也是生成class文件。
   枚举也是一种引用数据类型。
   枚举中的每一个值可以看作是常量。
2、定义枚举类型的语法结构:
   [修饰符列表] enum 枚举类型名 {
       枚举类型值1,
       枚举类型值2,
       枚举类型值3,
       ...
   }
   public enum Result {
       SUCCESS,//成功,枚举成员名是合法的标识符一般全部大写【引用方式:Result r = Result.SUCCESS;//SUCCESS】
       FAIL,//失败,多个枚举成员之间用逗号分割【引用方式:Result r = Result.FAIL;//FAIL】
   }
3、枚举类型的文件名也是“.java”,编译之后也是生成“.class”的文件。

java异常处理机制
1、什么是异常,异常机制有什么用?
   程序在执行过程中发生了不正常的情况,而这种不正常的情况叫做:异常。
   java语言提供了异常处理方式,如果程序执行过程中出现了不正常的情况,JVM把异常信息输出打印到控制台,供程序员参考。程序员看到异常信息之后,可以对程序进行修改,让程序更加健壮。
2、异常在java中以类和对象的形式存在,异常类也重写了toString()方法,每一个异常类都可以创建异常对象。
3、JVM在执行程序的时候碰到异常,会自己new一个异常对象,并且抛出去。
4、异常类的继承关系:
    java.lang.Object
        java.lang.Throwable
            java.lang.Exception和java.lang.Error;所有以实现的接口:Serializable【可序列化的】
5、UML是一种统一建模语言。只要是面向对象的语言都有UML图,在UML图中可以描述类与类之间的关系,程序执行的流程,对象的状态等。
6、java.lang.Error和java.lang.Exception
   不管是“错误”还是“异常”,都是可抛出的都实现了Throwable接口.
   Error:所有的错误只要发生,JVM只能终止程序执行,错误无法通过程序处理。
   Exception:异常可以通过java程序处理。
7、java.lang.Exception分为两种(所有的异常都是发生在运行阶段):
    RuntimeException运行时异常(又叫免检异常):编写程序阶段可以选择处理,也可以选择不处理。
    除了RuntimeException异常Exception的直接子类都是编译时异常(又叫必检异常):表示必须在编写程序的时候预先对这种异常进行处理,如果不处理编译器报错。[虽然叫做编译时异常但并不是异常是发生在编译阶段]
8、编译时异常一般发生的概率比较高,所以编译器要求必须处理。
   运行时异常一般发生的概率比较低,所以可以选择处理也可以选择不处理。
9、假设java没有对异常进行划分,没有分为编译时异常和运行时异常,所有的异常都需要在编译时对其进行处理,将会是怎样?
    首先这样的话程序肯定是绝对的安全,但是程序员太累,代码到处都是处理异常的代码。
    所以java对异常进行了区分,对于发生概率较低的异常可以对其不进行处理。
10、java语言对异常的处理包括两种方式:
    第一种方式:在“方法”声明的位置上,使用throws关键字,抛给上一级。谁调用本方法,就抛给谁。
    第二种方式:就是使用try...catch语句进行异常的捕捉。
11、如果没有对运行时异常进行处理的话,如果真的发生异常那么默认的处理方式是“向上抛出”。
    一级一级往上抛,最后JVM默认是调用异常对象的printStackTrace()方法在控制台打印异常信息。
    就算是方法头部没有用throws关键字抛出也是默认往上抛的。
    抛出异常之后异常以后的语句就不在执行了。
12、语法结构:
    第一种方式(上抛):
        [修饰符列表] 返回值类型 方法名(形式参数列表) throws 异常类型1,异常类型2... {
            方法体;
        }
        例: public void doSome() throws Exception {}
        //throws的异常类型是Exception,所以该方法执行过程中有可能会出现Exception类型的异常或者Exception类型的子类型异常。
        //为什么是throws,因为方法内部可能抛出多个该类型的异常。
        //在方法内部抛出异常使用“throw”关键字: throw new 异常类型();
        //使用throws和throw都是往上“抛出”的方式。
    第二种方式(直接捕捉):
        try {
            //可能会出现异常的代码片段;
        } catch (捕获的异常的类型1 exception) {  //可以捕获到“捕获的异常的类型1”及“捕获的异常的类型1”的子类型异常
            //发生异常后的“处理逻辑”代码;
          } catch (捕获的异常的类型2 exception) {  //可以捕获到“捕获的异常的类型2”及“捕获的异常的类型2”的子类型异常
            //发生异常后的“处理逻辑”代码;
          } finally {
            //无论异常发生或者是不发生都会执行的代码片段;
            //finally语句块不能单独出现,必须和try语句块一起使用。
        }
        //“捕获的异常的类型1”不能是“捕获的异常的类型2”的父类型【“捕获的异常的类型1”不能已经包含“捕获的异常的类型2”,因为JVM是从上往下匹配的】。
13、代码:
    public static void main(String[] args) {
        //throw new ClassNotFoundException("123");编译报错,只要在此处有编译时异常抛出,必须处理(上抛或捕捉两种方式都可以)
        new ClassNotFoundException("123");//编译通过
    }
    public static void main(String[] args) {
        System.out.println(10 / 0);//这里JVM会做一件事情throw new ArithmeticException("/ by zero");
        //由于ArithmeticException的直接父类是RuntimeException所以可以不用处理
    }
14、Exception的直接子类是包括RuntimeException和其他直接子类:“其他直接子类”都是编译时异常(必检异常),RuntimeException下的子类是运行时异常(免检异常)
    总之编译时异常必须手动处理(上抛或捕捉两种方式都可以),运行时异常不处理默认是上抛(JVM自动通过throw new 异常类型名(实参列表)的方式抛出)。
15、一般不建议在main方法上使用throws,因为这个异常如果真的发生了,一定会抛给JVM。JVM只有终止。异常处理机制就是为了增强程序的健壮性,应该能做到异常发生了也不影响程序的正常执行,而不是JVM停止工作,所以main方法的异常不建议上抛。
    main方法中建议使用try...catch...,不建议往上抛。
16、编译时异常和运行时异常直接new对象只要不“往外抛出(用throw关键字)”都没事(不用处理)。
    方法名上用throws关键字叫做往上抛。
    用throw关键字用于手动往外抛出异常:JVM碰到异常也是通过throw关键字往外抛的
        对于“编译时异常”必须手动进行处理(上抛或捕捉两种方式都可以)
        对于“运行时异常”可以不对其进行手动处理。(如果异常真的发生了,默认是往上抛的)
17、同一个作用域中throw后面不能有java语句,执行不到。
    同一个作用域中只要执行代码的过程中抛出了异常,异常之后的java语句就不再执行了。
18、throws只能用在方法头部。
19、一般在某个方法中采用throw关键字抛出异常,不在本方法中直接进行捕捉(因为在某个方法中抛出一个异常,程序员已经知道了会出现某个异常,直接进行处理就行了,没有必要抛一下再捕捉),而是通过throws关键字继续往上抛。
    所以在某个方法中用throw抛出的异常是给调用者看的,告诉调用者出现了异常,调用者怎么处理调用者自己决定。
20、JDK8新特性:多个异常类型可以使用“|”隔开
    try {
    } catch (类型1 | 类型2...  变量名) {//各个类型之间不能存在包含关系,如果存在包含关系的范围较大的不报错,被包含的小范围的类型编译报错
    } 
21、catch后面的小括号中只能是Throwable类型的。
    throw 类型;//这里的类型也只能是Throwable类型的。
22、所有的异常对象都有这两个常用方法:
    1.String getMessage();//获取异常简单描述信息:这个信息就是异常类构造方法中的String参数
    2.void printStackTrace();//打印异常追踪的堆栈信息:实际上后台是专门有一个线程专门负责这件事情的(异步线程)。
23、只有try和finally,没有catch也可以:
    try {
        System.out.println("try...");
        return;
    } finally {
        System.out.println("finally...");
    }
    //try不能单独使用,但是try和finally可以联合使用
    //以上代码执行的顺序:
        先执行try...
        再执行finally...
        最后执行 return (return语句只要执行方法必然结束)
        本例try中有return语句try和finally语句块之后就不能再写语句了因为执行不到编译报错。
    try {
        System.out.println("try...");
        System.exit(0);//这样后面的finally语句块中的代码就不执行了,只有这一招能治他
    } finally {
        System.out.println("finally...");
    }
24、代码片段:
    public static int m () {
        int i = 100;
        try {
            return i;
        } finally {
            i++;
        }
    }
    理解:
        java语法规则1:方法体中的代码是自上而下执行的。
        java语法规则2:return语句一旦执行,整个方法必须结束 。
        java语法规则3:finally语句块中的代码还必须是执行的。
        所以:
            return i;出现在i=100下面,所以最终返回的结果必须是100,
            return语句还必须是保证最后执行的。
    所以反编译之后的代码如下:
    public static int m() {
        int i = 100;
        int var1;
        try {
            var1 = i;
        } finally {
            ++i;
        }
        return var1;
    }
25、自定义异常:
    1.SUN提供的JDK内置的异常肯定是不够用的。再实际的开发中,有很多业务,这些业务出现异常之后,JDK中都是没有的,需要自定义异常类。
    2.java中怎样自定义异常?
        第一步:编写一个类继承Exeption或者RuntimeException.
        第二步:提供两个构造方法,一个无参的,一个带有String参数的。
        例题:
        public class MyException extends Exception {
            public MyException () {}
            public MyException (String s) {super(s);}
        }    


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薛英豪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值