Java 知识点总结

这篇是参考Java快速教程之后的一份学习笔记

基础

Hello World 到面向对象
  • 类(class):上面程序定义了一个类HelloWorld,该类的名字与.java文件的名字相同。
  • 方法(method):类的内部定义了该类的一个方法main。
  • 语句(statement):真正的“打印”功能由一个语句实现,即: System.out.println(“Hello World!”);
  • 使用javac编译,使用java运行
  • Java不同变量类型在程序中的内存分布
类型 存储大小 例值 注释
byte 1byte 3 字节
int 4bytes 3 整数
short 2bytes 3 短整数
long 8bytes 3 长整数
float 4bytes 1.2 单精度浮点数
double 8bytes 1.2 双精度浮点数
char 2bytes ‘a’ 字符
boolean 1bit true 布尔值
  • Java 数组声明和定义
    • 声明:int[] a;
    • 声明的同时使用new来创建数组所需空间:int[] a = new int[100];
    • 声明创建同时指定元素内容:int[] a = new int[]{1,3,5,7,9};
  • 表达式
    • 数学表达式: +,-,*,/,%
    • 关系表达式:>,>=,==,<=,<,!=
    • 布尔表达式:&&,||,!
    • 位运算:&,|,^,~,<<,>>
    • 双目表达式:condition? X1:X2
  • 控制结构
    • 选择结构
      • if else
      • switch
    • 循环结构:
      • while
      • do{} while()
      • for(){}
    • break
    • continue
方法和数据对象
  • Java 使用return来返回值
  • this 指代的是对象本身
  • 成员方法可以添加参数列表
  • 使用 this.method() 调用同一对象的其他方法
  • 显式初始化:声明对象时候,对于对象进行赋值
构造器以及重载
  • 构造器定义函数值: 类似于C语言中的构造函数
  • 构建方法 > 显式初始值 > 默认初始值
  • Java根据方法名和参数列表决定要调用的方法,叫做方法重载
封装和接口
  • 三种不同的封装方法
    • public
    • private
    • protected: 标记为protected的成员变量在该类和该类的衍生类中可见,但不能被外界访问。
  • interface 接口
    • interface 可以定义接口
    • implements 可以实现接口
    • 可以实现一个类 实现多个接口
  • has-a 关系 一个对象可以拥有另一个对象 (手电筒有电池)
  • package : 将Java程序代码进行打包,使用包进行访问
  • JVM,实现程序的可移植性
  • extends 继承
    • 新类称之为衍生类
    • 同名同参数方法会存在方法覆盖
    • 使用super访问父层的方法
    • 基类对象先被创建和进行初始化,结束之后,开始构建衍生层(衍生层对象进行创建和初始化)
类数据和类方法
  • 类数据对象: 所有成员进行共享的变量 使用关键字 static
  • 类方法:操作类对象的方法使用关键字static, 使用这个关键字的方法不能正常操作属于对象的数据和方法
  • 对象方法可以访问类数据
  • final 关键字:这个数据 / 类 / 方法不能被改变了, private 方法默认为final方法
接口继承和抽象类
  • 接口的继承: 和类的继承类似, 可以添加设计更多的方法,不同点,可以实现多重继承
  • 抽象类:只提供类的原型,不提供类的具体实现。
Java 对象引用
  • new 在内存中为对象开辟了空间,在内存的堆上开辟了空间。
  • 对象引用存储在内存的栈中
  • 当我们将一个引用赋值给另一个引用的时候,我们实际上复制的是对象的地址,两个引用将操作同一个对象。当程序通过一个引用修改了对象之后,通过其他引用课也可以看到该修改。
  • 垃圾回收机制:当一个对象没有引用指向的时候,这个对象就会被清空。
  • Java 参数传递:Java的参数传递为值传递。当我们传递一个参数时,方法将获得该参数的一个拷贝。
    • 基本对象的参数传递:传递的是值的拷贝,Java方法不会影响到值,形式变量和实际变量。
    • 引用值的参数传递: 传递的是对象的地址,Java方法会直接影响到对象。
类型转换和多态
  • 类型检查
  • 基本类型检查: 收缩类型变换(强制类型转换),宽松变换(自动进行)
  • Upcast 和多态:一个衍生类可以转换为其基类引用
  • 一个衍生类对象可以当做一个基类对象使用
  • 所有对象都有一个共同的继承祖先,Object

进阶

String 类
  • 创建字符串 不需要new关键字

  • Java String 类别中的常用方法

    方法 效果
    s.length() 返回字符串s的长度
    s.charAt() 返回字符串中下标为2的字符
    s.substring(0,4) 返回s字符串中下标0-4的子字符串
    s.indexOf(“Hello”) 返回子字符串”Hello“的下标
    s.startsWith(“ “) 返回s是否以空格开始
    s.endsWith(“oo”) 判断s是否以”oo”结束
    s.equals(“Good World!”) 判断s是否等于”Good World!”, ==只能判断字符串是否保存在同一位置。需要使用equals()判断字符串的内容是否相同。
    s.compareTo(“Hello Nerd!”) 比较s字符串与”Hello Nerd!”在词典中的顺序,返回一个整数,如果<0,说明s在”Hello Nerd!”之前;如果>0,说明s在”Hello Nerd!”之后;如果==0,说明s与”Hello Nerd!”相等。
    s.trim() 去掉s前后的空格字符串,并返回新的字符串
    s.toUpperCase() 将s转换为大写字母,并返回新的字符串
    s.toLowerCase() 将s转换为小写字母,并返回新的字符串
    s.replace(“World”, “Universe”) 将”World”替换为”Universe”,并返回新的字符串
  • String 类型对象是不可变对象

异常处理
  • try, catch, finally 以及其随后的代码段来组成,finally 不是必须的
  • try后面的程序块包含了针对该异常类型所要进行的操作。try所监视的程序块可能抛出不止一种类型的异常,所以一个异常处理器可以有多个catch模块。finally后面的程序块是无论是否发生异常,都要执行的程序。
  • 异常都来自与Throwable类,一个Throwable类对象可以抛出,异常分为unchecked 异常和checked异常。
  • Error是指Java的内部错误或者是资源耗尽等错误,需要直接退出程序。
  • Exception里面一个衍生类RuntimeException 都是程序自身的问题组成的。
  • checked 异常,是由编程与环境
  • 可以自己新建类,在程序中抛出异常
  • 可以自定义异常,使用继承的方式,需要小心选择所继承的基类。
运行时类别识别(RTTI)
  • Class类:对类的抽象和集合。当我们调用对象的getClass()的时候,就会得到其对应Class对象的引用
  • Class类方法
    • getName() 返回类的名字
    • getPackage()返回类所在的包
    • getFields()返回所有的public数据成员
    • getMethods()返回所有的public方法
多线程
  • 多线程是计算机实现多任务并行处理的一种方式
  • 单核CPU会在不同的任务之间做切换,这是操作系统分时复用的机制
  • 多个线程可以并存于同一个进程空间。在JVM的一个进程空间中,一个栈(stack)代表了方法调用的次序。对于多线程来说,进程空间中需要有多个栈,以记录不同线程的调用次序。多个栈互不影响,但所有的线程将共享堆(heap)中的对象。
  • Thread基类的构造方法可以使用一个字符串作为参数,该字符串是该线程的名字,并使用getName()返回。
    • 我们调用线程对象的start() 方法启动线程
    • join(Thread tr): 等待线程tr完成
    • setDaemon(): 设置当前线程为后台daemon
  • 另一种实现多线程的方法是实现Runable接口,并提供run()方法
  • Synchronized: 进程之间的同步,防止出现超票的情况
    • 我们将共享的资源置于一个对象中
    • 对于共享资源的操作,放在synchronized方法中
容器
  • 数组

    • 在说明类型时,在类型说明后面增加一个[],来说明是一个数组。

    • 使用new创建容器时,需要说明数组的大小。我们可以使用 数组名[下标] 的方式来调用某个元素。

    • 我们可以逐个的初始化数组的元素,也可以在声明的同时使用{}初始化数组。

    • 使用System.arraycopy()方法来有效的复制数组

    • 1
      2
      System.arraycopy(aFrom, 1, aTo, 0, 3);
      //aFrom为想要复制出去的数组,aTo为想要复制到的数组,1为aFrom的想要复制出去的元素起始位置,0为aTo中想要存储复制来元素的起始位置,3为所要复制的元素总数。
  • Collection

    • List
      • 容器的引用为List类型, 但是容器的实施类型为ArrayList类型。
      • 将接口和实施做分离
    1
    2
    3
    4
    5
    6
    import java.util.*;
    List<String> l1 = new ArrayList<String>();
    add();//方法加入新的元素
    get();//方法可以获取容器中的元素,传递一个整数下标作为参数
    remove();//方法可以删除容器中的元素,传递一个整数下标作为参数。(有另一个remove(),传递元素自身作为参数)
    size();//方法用来返回容器中元素的总数
    • Set 集合

      • 集合中不允许有等值的元素
      • 集合的元素没有顺序
    • Map 键值对的集合

      Java-1

    • Collection

      • 主要方法:

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        boolean add(Object o);//添加对象到集合
        boolean addAll(Collection c);//将指定 collection 中的所有元素都添加到此 collection 中(可选操作
        void clear();//删除集合中所有元素
        boolean remove(Object o);//删除指定的对象
        boolean removeAll(Collection c);//移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。
        boolean retainAll(Collection c);//仅保留此 collection 中那些也包含在指定 collection 的元素(可选操作)。
        int size();//返回当前集合中元素的数量
        boolean contains(Object o);//查找集合中是否有指定的对象
        boolean containsAll(Collection c);//查找集合中是否有集合c中的元素
        boolean isEmpty();//判断集合是否为空
        Iterator iterator();//返回一个迭代器
    • iterator 接口:不论Collection 的实际类型是什么,都支持一个iterator()的方法,该方法返回一个迭代子,使用该迭代子可以逐一访问Collection里面的元素。

      1
      2
      3
      boolean hasNext(); //如果仍有元素可以迭代,则返回True
      E next(); //返回下一个迭代的元素
      void next(); //将迭代器指向的集合中,移除迭代器返回的最后一个元素
    • List 接口: 有序的Collection,使用这个接口可以精确的控制每个元素插入的位置,用户可以使用索引(下标的方式)对于对象进行访问。

      • LinkedList 类:允许null元素,提供额外的get,remove,insert 方法,并不是线程安全的,注意它没有同步方法,需要自己新建。
      • ArrayList类:实现了一个大小可变的数组,允许null元素,没有同步方法。
      • 快速添加删除,使用LinkedList,需要快速随机访问元素,使用ArrayList
      • Vector类:类似于ArrayList,但是存在的同步方法,是线程安全的,使用Iterator进行遍历操作时候,不同线程对于同一个对象操作会产生异常。`
      • Stack类:继承自Vector, 实现了一个后进先出的栈,提供5个额外的方法使得Vector能够当做栈来使用,push, pop,peek, empty,search,刚开始创建的时候是空栈。
    • Set接口: 不包含重复元素的Collection

      • HashSet: 方法有add(),remove(元素) ,旗下还有实现类LinkedHashSet
      • TreeSet: 是Set的一种变体,可以实现按照树型进行插入,实现元素的排序(从小到大)
    • Map接口: 没有实现Collection类,提供从key到value的一种映射。

      • Map接口需要实现的方法有:

        put/putAll/remove/clear 增加删除

        get/values 获取值

        containKey/containValue 判断

        entrySet/keySet 获取迭代

        equals/hashcode 比较

      • HashMap 类: 非进程同步的

      • HashTable类:进程同步的

      • TreeMap类:Map数据是根据key来进行排序的

嵌套类
  • 内部类

    • Java 允许我们在一个类中嵌套另一个类, 在类的内部定义一个新类,这个类称为内部类

    • 内部类是被认为是外部对象的一个成员,在定义内部类的时候,同样有访问权限控制(public, private, protected)

    • 内部类的默认访问权限是包访问权限,我们可以在外部测试类中访问到对象的内部类,并使用该内部类创建对象。

      1
      Human.Cup soloCup = me.new Cup();

      在创建对象的时候,要注意必须基于一个外部类,并使用这个外部类对象来创建Cup对象。

  • 闭包

    • 内部类对象必须依附于某个外部类对象,与此同时,内部类对象也可以访问到它所依附的外部类对象的成员(即便是private成员)。从另一个角度来讲,内部类对象附带有创建对象时的环境信息。
  • 嵌套static类

    • 我们可以定义嵌套的static类,对象不需要依附于外部类的某个对象。相应的,这个嵌套类也无法调用外部对象的方法,也无法读取或者修改外部对象的数据。效果上看,就是扩展了类的命名空间。
GUI 图形界面以及事件响应
  • Java GUI 功能主要集中在awt和swing中。awt是GUI的底层包。
  • Java Layout 布局方式:Java 里面存在着不同的布局方式。Java布局方式
  • 元素,事件,监听器: 通过监听器,可以将事件绑定在图形元素上面 ActionListener, ActionEvent class
内存管理和垃圾回收
  • Java 是在JVM所虚拟出来的内存环境中运行的。

  • 内存分为栈stack和堆heap 两个部分

    • 记录了线程的方法调用,每个线程有一个栈
    • 如果有新的方法调用,那么栈会增长
    • 栈的存储单元为帧(frame)
    • 栈中保存基本变量类型的变量值,以及对象的引用,引用指向堆
    • 调用结束之后,栈会被释放
    • 堆的空间不会随着方法调用结束而清空,因此,在某个方法中创建的对象,可以在方法调用结束之后,继续存在于堆中。
  • 垃圾回收 Garbage Collection (GC)

    • 垃圾回收负责释放不可到达的对象(即没有引用的指向的对象)

    • 早期垃圾回收采用引用计数机制,但是存在循环引用不可处理的问题

    • “mark and sweep”: 这种机制下,每个对象将有标记信息,用于表示该对象是否可到达。当垃圾回收启动时,Java程序暂停运行。JVM从根出发,找到所有的可到达对象,并标记(mark)。随后,JVM需要扫描整个堆,找到剩余的对象,并清空这些对象所占据的内存。

    • “copy and sweep”。这种机制下,堆被分为两个区域。对象总存活于两个区域中的一个。当垃圾回收启动时,Java程序暂停运行。JVM从根出发,找到可到达对象,将可到达对象复制到空白区域中并紧密排列,修改由于对象移动所造成的引用地址的变化。最后,直接清空对象原先存活的整个区域,使其成为新的空白区域。

    • 这两种机制, “mark and sweep”, “copy and sweep” 都是通过分代回收来进行回收的。

    • 每个对象会记录它的世代信息,世代就是指对该对象所经历的垃圾分类回收的次数,世代越久远的对象,在内存中存活的时间就越长。

    • generation

      在上图中,堆分为三代,其中永久世代不会被垃圾回收,里面存储的是Class和类相关的信息。年轻世代和成熟世代需要进行垃圾回收。年轻世代需要分为三个区域,第一个区域叫做伊甸,新生对象将存在于这个区域。from, to: 这两个区域大小相等,相当于copy and sweep中的两个区域。当新建对象无法放入eden区时,将出发minor collection。JVM采用copy and sweep的策略,将eden区与from区的可到达对象复制到to区。经过一次垃圾回收,eden区和from区清空,to区中则紧密的存放着存活对象。随后,from区成为新的to区, to区成为新的from区。如果进行minor collection的时候,发现to区放不下,则将部分对象放入成熟世代。另一方面,即使to区没有满,JVM依然会移动世代足够久远的对象到成熟世代。

参考资料

文章作者:Xingjiali Zhang

最后更新:2019年07月29日 19:07:26

原始链接:http://yoursite.com/2019/07/26/Java/

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 3.0 许可协议,转载请注明出处!