文章

java - 基础知识

java - 基础知识

内存结构

  • 栈 存放局部变量
  • 堆 存放对象,数组

  • 变量 成员变量 vs 局部变量(方法内,方法形参,构造器,构造器形参,代码块内)

四种访问权限修饰符

修饰符类内部同一个包不同包的子类同一个工程
privateyes   
defaultyesyes  
protectedyesyesyes 
publicyesyesyesyes

对于class的修饰符只有public 和default

JavaBean 符合以下标准的类

  • 类是公共的
  • 有一个无参的公共构造器
  • 有属性,且有对应的get,set方法

用户可以使用JavaBean 将功能,处理,值,数据库访问和其他任何可以用java代码创造的对象进行打包,并且其他的开发者可以通过内部的JSP页面,Servlet,其他JavaBean,applet程序或者应用来使用这些对象。用户可以认为JavaBean 提供了一种随时随地的复制和赞贴的功能,而不用关心任何改变。

this

  • this可以调用属性,方法,构造器
  • this() 调用构造器,可以显示的使用this(形参列表)方式,调用指定的其他构造器,不能形成递归

继承

  • 子类继承后,具有父类的所有属性和方法 ,private属性和方法仍然认为获取到了,但是因为封装的原因,不能直接调用
  • 所有的java类处 java.lang.Object 外,都直接或者间接继承了java.lang.Object类
  • 当子类和父类中定义同名属性时,我们想要在子类调用父类中的属性方式,必须使用“super.属性”,子类不会覆盖父类的属性
  • 我们可以在子类构造器中显示的使用super(形参列表),调用父类的构造器,必须声明在子类构造器的首行
  • 在构造器的首行没有显示的声明this(形参列表)或super(形参列表),则默认调用的是父类的空参的构造函数

子类对象的实例化过程

  • 从结果来看 子类继承父类以后,就获取了父类所有的属性和方法
  • 创建子类的对象后,在堆空间中,就会加载所有父类中声明的属性
  • 从过程看 当我们通过子类的构造器创建子类对象时,我们一定会直接或者间接的调用父类的构造器,直到调用了java.lang.Object类中空参的构造器为止。正因为加载过所有父类的结构,所有内存中才会有所有父类的结构,并且使用。
  • 虽然创建子类对象时,调用了父类的构造器,但是只创建了一个对象,就是new 出来的对象

多态性

  • 对象的多态性,父类的引用指向子类的对象

多态的使用

  • 当调用子父类同名同参方法时,执行的是子类重写父类的方法
  • 编译期,只能调用父类中声明的方法 ,但是运行期,我们实际执行的是子类重写的方法 只适用方法,编译看左边,运行看右边
  • 对象的多态性,只使用于方法,不适用于属性。 编译和运行都看左边。
  • 虚拟方法调用 子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法称为虚拟方法,父类根据赋给它不同子类对象,动态调用属于子类的的该方法,这样的方法调用在编译器是无法确定的。
  • 编译时类型和运行时类型。方法调用是在运行时确定的,动态绑定。
  • 多态是个运行时行为
  • 若子类重写了父类的方法,就意味着子类里定义的方法彻底覆盖了父类里的同名方法,系统将不可能把父类的的方法转移到子类中。(编译看左边,运行看右边)
  • 对于实例变量则不存在这样的现象,即使子类里定义了与父类完全相同的实例变量,这个实例变量依然不可能覆盖父类中定义的实例变量(编译运行都看左边)

## 方法的重写

  • 方法名,形参列表相同
  • 权限修饰符不能小于父类,不能重写private权限的方法
  • 返回值不能大于父类的返回类型,
  • static 方法不涉及到重写

静态变量

  • 静态变量随着类的加载而加载
  • 静态变量加载要早于对象的创建
  • 类只会加载一次, 静态变量也只会存在一份

静态方法

  • 只能调用静态变量或者其他静态方法,因为是随着类的加载而加载,其他实例变量还没有,所以this,super是不能用的。

栈,堆,方法区

  • 栈,静态变量
  • 堆:new 出来的结构 对象,数组
  • 方法区: 类的加载信息,静态域,常量池

抽象与接口

抽象

  • 抽象类,不可以实例化,一定有构造器,便于子类实例化时调用,通常在开发中,都会提供抽象类的子类,让子类对象实例化。
  • 抽象方法,没有方法体,只有声明。 抽象方法一定是在抽象类。
  • 若子类重写了父类的所有 抽象方法后,则此子类可以实例化,若子类没有重写父类的所有的抽象方法,则此子类也是一个抽象类,需要使用abstract修饰。

接口

  • interface和类是并列的结构,通过implements
  • 如何定义接口:JDK7及以前 只能定义全局常量和抽象方法(public static final(书写时可以省略),public abstarct)
  • JDK8 新增了 静态方法和默认方法。
  • 接口中是不可以定义构造器的,意味着接口不可以实例化
  • 如果实现类覆盖了接口中所有的抽象方法,则此实现类可以实例化,如果没有则实现类认为接口
  • java类可以实现多个接口,弥补了java单继承性
  • 接口与接口之间可以继承,并且可以多继承 ### jdk8 新特性
  • 静态方法和默认方法
  • 接口中定义的静态方法,只能通过接口调用
  • 通过实现类的对象,可以调用接口中的默认方法
  • 如果子类继承的父类和实现的接口中声明了同名同参数的默认方法,那么子类在没有重写此方法的情况下,默认调用的是父类中同名同参数默认(default)方法
  • 接口冲突: 如果实现类实现了多个接口,而这多个接口中定了同名同参数的默认方法,那么实现类没有重写此方法的情况下报错
  • 调用接口中的默认方法 Interface.super.method()

## 抽象类和接口的共同点以及区别

  • 相同点: 不能实例化,都可以被继承
  • 不同 抽象类:有构造器, 接口:不能声明构造器 ,类单继承,接口可以多继承

异常处理

### ERROR 一般不编写针对性的代码进行处理 java虚拟机无法解决的严重问题,如JVM系统内部错误,资源耗尽等严重情况,例如栈溢出:StackOverflowError,堆溢出:OutOfMemoryError,

### Exception

  • 其他编程错误或偶然的外在因素导致的,可以使用针对性的代码进行处理
  • 例如空指针,数组越界,除数为0
  • 一般两种解决方法,遇到错误终止程序的运行。另一种方法时由程序编写程序时,考虑到错误的检测,错误消息的提示,以及处理。
  • finally 是可选的,finally 中声明的是一定会被执行的代码,即使catch中又出了异常,try中有return语句,catch中有return 语句等, 也会先执行finally的语句。
  • 像数据库连接,输入输出流,网络编程Socket 等资源,JVM是不能自动回收的,我们需要自己手动的进行资源的释放。此时的资源释放,就需要声明在finally中 ### 体会
    • 使用try-catch-finally 处理编译时异常,是将编译时可能出现的异常,延迟到运行时出现
    • 开发中,由于运行时异常比较常见,所以我们通常就不针对运行时编译try-catch-finally
本文由作者按照 CC BY 4.0 进行授权