二次学习未知知识点

  • 事实上没有对象变量这种东西。
  • 只有引用到对象的变量。
  • 对象引用变量保存的是存取对象的方法。
  • 他不是对象的容器,而是类似指向对象的地址。或者可以说是地址。但是在Java中我们不会也不该知道应用变量中的实际装载的是什么,它只是用来代表单一的对象。只有Java虚拟机才会知道如何使用来用来取得该对象。
  • Dog dog = new Dog
  • 声明一个引用变量,要求Java虚拟机分配空间给引用变量,并将此变量命名为dog。此引用变量被永久固定为Dog类型。
  • Dog dog = new Dog
  • 创建对象,要求Java虚拟机分配给堆空间给新建的Dog对象。
  • Dog dog = new Dog
  • 连接对象和引用,将新定义的Dog赋值给dog这个引用能量。
  • 数组也是对象。
  • 一旦数组被声明出来,你就只能装入所声明类型的元素。
  • 主数据类型的变量值是该值的字节所表示的。
  • 局部变量没有默认值!如果在变量被初始前就要使用的话,编译器会显示错误
  • ==比较的是两个数据是否引用的java.lang是个经常会用到的基础包,所以不用引用。
  • public类型的成员变量会被继承。
  • private类型的成员变量不会被继承。
  • 重写规约:
  • 参数必须要一样,且返回类型必须要兼容。
  • 不能降低方法的存取权限。
  • 重载:
  • 返回类型可以不同。
  • 不能只改变返回类型
  • 可以更改存取权限
  • 方法名要相同
  • 抽象类除了被继承过之外,是没有用途、没有值、没有目的。
  • 抽象方法必须被实现。
  • 如果你声明出一个抽象方法,就必须将类也标记为抽象的。你不能在非抽象类中拥有抽象方法。
  • 从ArrayList取出的Object都会被当做是 Object这个类的实例。编译器无法将此对象识别成Object以外的事务。
  • 编译器是根据引用类型来判断有哪些方法可以调用的,而不是根据Object确定的类型。
  • 所有接口的方法都是抽象的,所以任何实现接口的类,必须要实现这些方法。
  • 接口的方法一定是抽象的,所以必须以分号结束。接口的方法没有内容。
  • 类可以实现多个接口。
  • 对象的生存空间是堆。
  • 方法调用及变量的生存空间是栈。
  • 当Java虚拟机启动时,它会从底层的操作系统取得一块内存,并以此区段来执行Java程序。
  • 局部变量又称栈变量,局部变量和方法参数都是被声明在方法中。它们是暂时的,且生命周期只限于方法被放在栈上的这段期间,也就是方法调用至执行完毕为止。
  • 实例变量是声明在类中方法外的。它代表每个独立对象的字段,每个实例都能有不同的值,实例变量存在于所属的对象中。
  • 当你调用一个方法时,改该方法会放在调用栈的栈顶。实际上被堆上栈的是堆栈快,它带有方法的状就算你没有写构造函数,编译器也会帮你写一个。构造函数一定要与类名相同。
  • 构造函数有一个关键的特征,它会在对象能够被赋值给引用之前就执行。
  • 使用构造函数可以初始化对象的状态。
  • 如果你已经写了一个有参数的构造函数,并且你需要一个 没有参数的构造函数,这个时候需要手动写一个,编译器不会自动生成。
  • 如果类上有一个以上的构造函数,则参数一定要不一样。
  • 如果实例变量是个对对象的引用,则引用与对象都是在堆上。
  • 实例变量有默认值,原始的默认值是0/0.0/false。
  • 在创建新的对象时,所有继承下来的构造函数都会执行。
  • 新建一个子类,会执行子类与父类的构造函数,先执行父类的,再执行子类的。
  • 如果你没有在子类中编写构造函数,那么编译器会给我们加上构造函数,并在函数里调用super(),如果子类中编写了构造函数,但是没有在构造函数里编写super(),那么编译器会在我们的构造函数里加上super()。
  • 每个构造函数可以选择调用super()或者this(),但不能同时调用。
  • 使用this()从某个构造函数调用同一个类的另外一个 构造函数。
  • this()只能用在构造函数中,且必须是第一行语句。态,包括执行到哪一行程序以及所有的局部变量的值。同一个对象,比较的是地址值。

 

 

关于构造器重载方面,

构造器像一般方法一样,也可以重载。

例如:

public class Test {

 public static void main(String[] args) {

  Person person1 = new Person();//使用无参的构造器初始化

  Person person2 = new Person("张三");//使用一个名字参数的构造器初始化

  Person person3 = new Person("李四", 19);//使用两个参数的构造器初始化

 }

}

 

class Person {

 String name;

 int age;

 

 //无参构造器

 public Person() {

  this.name = "无名";

  this.age = 18;

 }

 

 //一个名字参数的构造器

 public Person(String name) {

  this.name = name;

  this.age = 18;

 }

 

 //两个参数的构造器

 public Person(String name, int age) {

  this.name = name;

  this.age = age;

 }

}

重载的规则与一般方法的规则也是一致的。 

 

补充一下细节:

1.构造器只完成对对象的初始化

构造器只完成对象的初始化,不会创建对象。

 

2.查看默认的构造器

上面我们说到,如果没有显示自定义构造器,Java编译器会自动提供一个无参的默认构造器。我们可以使用 javap 反编译查看这个构造器:

 

以下列代码为例,这里定义一个类,里面没有任何内容

class Cat {

}

然后我们使用 javac 指令进行编译,

然后使用 javap 反编译字节码文件,得到的内容如下:

我们可以看到这里是对应的一个方法的声明

 

构造器的继承

定义父类构造器,覆盖了默认的无参构造器,不能直接 new Father() 调用了,除非再定义一个无参构造器

 

//父类构造器

public class Father{

    

    //自定义带参构造器

    public Father(String str){

        System.out.println("父类的带参构造方法,参数为:"+str);

    }

    

}

定义子类构造器,继承Father,由于Father没有无参构造器,所以必须在子类构造器中通过 super(“字符串”)来调用,否则编译器会报错

 

//子类构造器

public class Son extends Father{

    

    //无参构造器

    public Son(){

        //由于Father()没有无参构造器,所以必须在子类型构造器中通过super("字符串")来调用,否则编译器会报错。

        //如果没定义这句,系统会默认调用super()

        super("");

    }

    

    //带参构造器

    public Son(String str){

        //由于Father()没有无参构造器,所以必须在子类型构造器中通过super("字符串")来调用,否则编译器会报错。

        //如果没定义这句,系统会默认调用super()

        super(str);      

    } 

}

 

 构造器、静态代码块、构造代码块的执行顺序


无继承的情况


public class Father {
    static {
        System.out.println("父类的静态代码块,程序启动后执行,只会执行一次");
    }

    //父类无参构造方法
    public Father(){
        System.out.println("父类的默认构造方法");
    }

    //重载,自定义父类带参构造方法
    public Father(String str){
         System.out.println("父类的带参构造方法,参数为:"+str);
    }
    
    {
        System.out.println("父类构造代码块,每次调用构造方法都会执行的");
    }
}
实例化Father

//实例化Father
    public static void main(String[] args) {
        System.out.println("---------------------------------------");
        Father father1 = new Father();
        System.out.println("---------------------------------------");
        Father father2 = new Father("阿马");
    }

执行上述代码

父类的静态代码块,程序启动后执行,只会执行一次

父类构造代码块,每次调用构造方法都会执行的


父类的默认构造方法
--------------------------------------


有继承的情况


定义父类Father

public class Father {
    
    static {
        System.out.println("父类的静态代码块,程序启动后执行,只会执行一次");
    }

    //父类无参构造方法
    public Father(){
        System.out.println("父类的默认构造方法");
    }

    //重载,自定义父类带参构造方法
    public Father(String str){
         System.out.println("父类的带参构造方法,参数为:"+str);
    }
    
    {
        System.out.println("父类构造代码块,每次调用构造方法都会执行的");
    }
}

定义子类Son,继承自父类Father

//子类构造器
public class Son extends Father{
    static {
        System.out.println("子类的静态代码块,程序启动后执行,只会执行一次,先执行父类的,在执行子类的");
    }
    {
        System.out.println("子类构造代码块,每次调用构造方法都会执行的");
    }

    //无参构造器
    public Son(){
        //这里没有指定调用父类的哪个构造方法,会默认调用super(),调用父类的无参构造器public Father()
    }

    //重载构造器,多传两个参数
    public Son(String str1,String str2){
        //必须写在构造器第一行,调用父类的带参构造器public Father(str)
        super(str1);
        System.out.println("子类带参构造器:"+str2);
    }
}

异常处理(整理)

  • Java中的所有异常都来⾃顶级⽗类Throwable,Throwable下有两个⼦类Exception和Error。
  • Throwable类,是所有异常类的根类,Java异常的顶层父类,所有的异常类都是由它继承。
  • Exception:异常,程序本身可以处理的异常。
  • Java中异常继承的根类是:Throwable。Throwable是根类,不是异常类。
  • Exception才是异常类,当程序出现Exception时,是可以靠程序⾃⼰来解决的,它才是开发中代码在编译或者执行的过程中可能出现的错误,它是需要提前处理的,以便程序更健壮!
  • 异常体系的最上层父类是Exception。
  • Exception的⼦类通常⼜可以分为RuntimeException和⾮RuntimeException两类
  • 异常分为两类:编译时异常(受检异常,必须处理)、运行时异常(非受检异常)。
  • 受检异常:就是程序必须手动处理的异常,如果不手动处理,则会编译失败。
  • 非受检异常:不强制程序处理的异常,不强制你手动处理,无需try...catch...,也无需throws,代码也能编译成功。
  • Error也属于非受检异常。
  • 编译时异常{受检异常-Checked Exception}:没有继承RuntimeException的异常,直接继承于Exception。编译阶段就会错误提示 / 报错,必须要手动处理(如果受检查异常没有被 catch或者throws 关键字处理的话,就没办法通过编译),否则代码报错不通过。编译时异常是为了提醒程序员,比如:IOException、ClassNotFoundException、ParseException、SQLException、java.io.FileNotFoundException...
  • 运行时异常{非受检异常-Unchecked Exception}:继承了RuntimeException,RuntimeException本身和子类。编译阶段不会报错 / 出现异常提醒,运行时出现的异常。运行时异常是代码出错而导致程序出现的问题。
     

一.Throwable体系:

 

a.Error:严重错误Error,无法通过处理的错误,只能事先避免,好比绝症。

b.Exception:表示异常,异常产生后程序员可以通过代码的方式纠正,使程序继续运行,是必须要处理的。好比感冒、阑尾炎。

Throwable中的常用方法:

a.public void printStackTrace():打印异常详细信息。

b.public String getMessage():获取发生异常的原因。

c.public String toString():获取异常的类型和异常描述信息(不用)。  

二.异常分类

        我们平常说的异常就是指Exception,因为这类异常一旦出现,我们就要对代码进行更正,修复程序。

异常(Exception)的分类:

a.编译时期异常:checked异常。在编译时期,就会检查,如果没有处理异常,则编译失败。(如日期格式化异常)。

b.运行时期异常:runtime异常。在运行时期,检查异常.在编译时期,运行异常不会编译器检测(不报错)。(如数学异常)。

三、异常的处理

         Java异常处理的五个关键字:try、catch、finally、throw、throws 。。

 

1.抛出异常throw

        在编写程序时,我们必须要考虑程序出现问题的情况。比如,在定义方法时,方法需要接受参数。那么,当调用方法使用接受到的参数时,首先需要先对参数数据进行合法的判断,数据若不合法,就应该告诉调用者,传递合法的数据进来。这时需要使用抛出异常的方式来告诉调用者。

 

在java中,提供了一个throw关键字,它用来抛出一个指定的异常对象。

 

a.创建一个异常对象。

b.需要将这个异常对象告知给调用者。

throw用在方法内,用来抛出一个异常对象,将这个异常对象传递到调用者处,并结束当前方法的执行。

使用格式:

thr例如:

throw new NullPointerException("要访问的arr数组不存在");

 

throw new ArrayIndexOutOfBoundsException("该索引在数组中不存在,已超出范围");

public class Test {

    public static void main(String[] args) {

        //创建一个数组 

        int[] arr = {2,4,52,2};

        //根据索引找对应的元素 

        int index = 4;

        int element = getElement(arr, index);

 

        System.out.println(element);

        System.out.println("over");

    }

    /*

     * 根据 索引找到数组中对应的元素

     */

    public static int getElement(int[] arr,int index){ 

        //判断索引是否越界

        if(index<0 || index>arr.length-1){

            

             throw new ArrayIndexOutOfBoundsException("角标越界了~~~");

        }

        int element = arr[index];

        return element;

    }

}

tips:如果产生了问题,我们就会throw将问题.声明异常throws

        声明异常:将问题标识出来,报告给调用者。如果方法内通过throw抛出了编译时异常,而没有捕获处理(稍后讲解该方式),那么必须通过throws进行声明,让调用者去处理。

 

关键字throws运用于方法声明上面,意思是当前方法不处理异常,来提醒该方法的调用者来处理异常(抛出异常)。

 

声明异常格式:

修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2…{ }    

声明异常的代码演示:

public class Test {

    public static void main(String[] args) throws FileNotFoundException {

        read("a.txt");

    }

 

    // 如果定义功能时有问题发生需要报告给调用者。可以通过在方法上使用throws关键字进行声明

    public static void read(String path) throws FileNotFoundException {

        if (!path.equals("a.txt")) {//如果不是 a.txt这个文件 

            throw new FileNotFoundException("文件不存在");

        }

    }

}

throws用于进行异常类的声明,若该方法可能有多种异常情况产生,那么在throws后面可以写多个异常类,用逗号隔开

 

public class Test {

    public static void main(String[] args) throws IOException {

        read("a.txt");

    }

 

    public static void read(String path)throws FileNotFoundException, IOException {

        if (!path.equals("a.txt")) {//如果不是 a.txt这个文件 

            throw new FileNotFoundException("文件不存在");

        }

        if (!path.equals("b.txt")) {

            throw new IOException();

        }

    }

}

描述类即异常进行抛出,也就是将问题返回给该方法的调用者。 ow new 异常类名(参数);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值