Java SE 学习笔记-Day 04

临时调用一个方法

// 非静态方法,需要创建一个匿名变量,直接调用
new Class().Method();
// 静态方法,不需要创建,直接调用即可
Class.staticMethod();

拆分窗口

Windows -> Editor Tabs -> Spilt Right

鼠标左键连击三下,选中这一行。双击选中一个词语。

构造器
  • 名字和类名相同,同时没有返回值,也不能写void
  • new本质是在调用构造器,而自定义了一个有参构造器,就会覆盖掉默认的无参构造,所以只要自定义了构造器,就要写一个无参构造(函数体为空就行)。
  • Alt + insert直接可以自动插入构造器、getter、setter等。
Java的内存分配

Java程序运行时的内存结构分成:方法区、栈内存、堆内存、本地方法栈

  • 方法区存放装载的类数据信息:
    ·基本信息:每个类的全限定名、每个类的直接超类的全限定名、该类是类还是接口、该类型的访问修饰符、直接超接口的全限定名的有序列表。
    ·每个已装载类的详细信息:运行时常量池、字段信息、方法信息、静态变量、到类classloader的引用、到类class的引用。
  • 栈内存
    Java栈内存由局部变量区、操作数栈、帧数据区组成,以帧的形式存放本地方法的调用状态(包括方法调用的参数、局部变量、中间结果……)。
  • 堆内存
    堆内存用来存放由new创建的对象和数组。在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。
  • 本地方法栈内存
    Java通过Java本地接口JNI(Java Native Interface)来调用其它语言编写的程序,在Java里面用native修饰符来描述一个方法是本地方法。

程序运行时,会将方法区的函数加载到栈中,首先加载main。创建的对象将会在堆中。方法区、静态变量、方法也都在堆中。为什么有了方法区保存代码还需要栈区,因为一个方法可能多次调用,如递归,所以需要用栈来保存多个方法的调用顺序、状态等。

面向对象三大特性

封装:高内聚低耦合。 高内聚是指要尽量将类的数据处理放在内部处理。低耦合是指类仅提供少量的接口供外部使用。

setter\getter可以通过ALT + INSERT自动生成

打印类属性的快捷输入: 输入Class.getXxx().sout,回车。

继承ctrl + H 将会出现类的继承层次。

  • Java中的类默认继承了Object类。
  • Java只能单继承,不能有多个父类。
  • super关键字就是用于访问类的父类,就像this指代类本身一样,可以通过super访问父类中与子类同名的属性。同时可以通过super()调用父类的构造器(默认无参),这句话在子类构造器中默认被调用了的(只能出现在第一行),可以显示调用有参,如super("a")。不能在一个方法中同时通过superthis调用构造器。

四种访问权限

  • public:都能访问
  • protected:子类可以访问,外部不能访问
  • default
  • private:子类无法访问

多态

  • 重载:方法名相同,参数列表不同

  • 重写:在基类与派生类中,存在函数名和参数列表都相同的函数。

    • 只能对非静态方法进行重写,因为非静态方法在类加载的时候就已经存在了,调用的使用不需要通过具体的对象。
    • 只能对父类的public方法
    • 修饰符:范围可以扩大但不能缩小: public > Protected > Defalut > private
    • 抛出的异常:范围只能缩小,但不能被扩大
    • static\final\private 方法 无法进行重写

使用父类类型引用子类对象时,只能调用父类中有的方法,不能调用子类中独有的方法(如果是重写了的即可),如果要调用子类方法,要进行强制类型转换为子类。

((Subclass)Obj).methodOfSubClass()
instanceof

对象名 instanceof 类名 :用于判断一个对象是否是某个类,是则返回true

  • 当对象与需要判断的类不在一条继承线上时(例如B和C都是继承的A,B、C为兄弟,就不在一条线上),过不了编译。
  • false 仅仅会出现在引用对象的 类型与要比较的类型存在继承关系
static 关键字
  • 静态方法不能调用非静态方法,因为静态方法在类加载时就存在了,与具体对象无关,所以不能调用非静态方法和访问非静态成员变量。

  • static方法内部不能使用this

  • static代码块:无论放在类的哪个位置,static代码块只会在类加载时执行一次,且在构造函数前执行(因为还未创建对象时,就执行了)。

    • 匿名代码块,将会在对象创建时执行,且在构造函数之前,无论它放在构造函数前还是后。同时它在静态代码块之后执行,可以用来完成一些对象的初始化工作。

      public class Person{
          static {
              System.out.println("静态代码块");
          }
         public Person(){
             System.out.println("构造函数");
         }
          {
              System.out.println("匿名代码块");
          }
      }
      
      // 执行顺序: 静态代码块 > 匿名代码块 > 构造函数
      
  • 静态导入包,在import之后加上static静态导入某个static方法或static属性后,可以不用加类名直接调用方法。如导入Math.random() 和 Math.PI

    import static java.lang.Math.PI;
    import static java.lang.Math.random;
    
    public class HelloWorld {
        public static void main(String[] args) {
            System.out.println(random());
    
        }
    }
    
abstract抽象
  • 抽象类不能实例化对象。
  • abstract修饰某个类,就说明这个类可以存在没有函数体的方法,同时方法也要用abstract修饰。
  • 某个非抽象类继承抽象类时,必须要实现这个抽象类的abstract方法,否则也声明为抽象类。
接口 - interface

普通类:只有实现

抽象类:具体实现和规范(抽象方法),不可实例化。

接口:只有规范,没有实现方法,所有方法都是抽象的,不可实例化,没有构造函数。

  • 接口类定义时,用interface代替class ,这样里面的所有方法都默认加了public static 修饰了。

  • 接口中定义的变量都是常量,即默认public static final,要在一开始就给初始化。

  • 可以使用implements代替extends,实现接口类,此时需要将接口类所有方法重写实现。

  • 通过extends普通类与抽象类只能单继承,通过implements可以实现多继承

内部类
  • 成员内部类:在类的内部定义一个类,该内部类可以直接访问外部类的私有成员变量和方法。

    注意实例化内部类时,需要通过外部类。外部类名.内部类名 对象名 = 外部对象名.new 内部类名()

    因为只有在外部类实例化了对象时,内部类才加载

    package Demo01;
    
    public class Outer {
       public  class Inner{
    	// 内部类
       }
    }
    
    
    public class HelloWorld {
        public static void main(String[] args) {
            Outer outer = new Outer();
            Outer.Inner inner = outer.new Inner(); //实例化内部类。
        }
    }
    
  • 静态内部类:在成员内部类的基础上,不过只能访问外部类的静态方法

  • 局部内部类:在一个方法内部定义一个类

  • 匿名对象类:new 一个接口然后实现

    interface A
    {
    }
    
    public class B{
    	new A(){
    	 @override
    	}
    }
    
异常

  • Error:表示运行应用程序中出现了严重的错误。此类错误一般表示代码运行时JVM出现问题。通常有Virtual MachineError(虚拟机运行错误)、NoClassDefFoundError(类定义错误)、StackOverFlow(栈溢出)、OutOfMemory(内存溢出)等。应用不应该去处理此类错误。
  • Exception:程序本身可以捕获并且可以处理的异常。
    • 运行时异常(非受检异常):编译器不会检查此类异常,并且不要求处理异常,比如用空值对象的引用(NullPointerException)、数组下标越界(ArrayIndexOutBoundException)、算术异常(ArithmeticException)。此类异常属于不可查异常,一般是由程序逻辑错误引起的,在程序中可以选择捕获处理,也可以不处理
    • 非运行时异常(受检异常):Exception中除RuntimeException极其子类之外的异常。编译器会检查此类异常,如果程序中出现此类异常,比如说IOException,必须对该异常进行处理,要么使用try-catch捕获,要么使用throws语句抛出,否则编译不通过。

捕获异常

try{
   // 需要监控的代码
} catch ( 异常类型 ){
   // 异常处理方式
} catch ( 异常类型 ){
   // 异常处理方式
} finally{
   // 善后工作
}
  • finally 代码块无论异常是否捕获到,是否处理,都会执行,一般用于关闭IO、文件等资源的关闭
  • 多个catch 代码块要将基类异常类型的(Throwable最高)放在后面。
  • 选中代码,快捷键ctrl + alt + T自动包含代码
  • try要和catch或者 finally一起使用, finally可选

throw 与 throws

  • throw 主动抛出异常,配合new使用。当没有try/catch时,也可以使用。

  • throws放在方法上,该方法将捕获的异常继续抛出

    public void div(int a, int b) throws ArithmeticException
    {
        if(b == 0)
        {
            throw new ArithmeticException();  // 方法中抛出异常
        }
    }
    

自定义异常

即自己自定义一个异常类,继承Exception,写一个构造器(将异常信息保存在这个异常类里面),重载一个toString()(相当于将异常信息以何种格式输出)即可。

// 自定义异常
public class MyException extends Exception{
    int detail;
    public MyException(int a){
        detail = a;
    }

    @Override
    public String toString() {
        return "detail = "+detail;
    }
}
// 捕获异常 并打印
public class HelloWorld {
    public static void main(String[] args) {
        try {
            sub(2);
        } catch (MyException e) {
            e.printStackTrace(); // 打印输出异常信息
        }
    }

    public static void sub(int a) throws MyException {
        if(a == 2)
            throw new MyException(2);
    }
}

IDEA代码格式化

Ctrl + Alt + L

posted @ 2021-03-09 20:51  蓬飞  阅读(49)  评论(0)    收藏  举报