zoukankan      html  css  js  c++  java
  • Java 基础复习

    P10 Windows 常用快捷键

    • Alt+F4 关闭窗口键

    P11 常用 Dos 命令

    • 在文件夹的路径前面(地址栏),输入 CMD,即可在对应文件夹下打开 CMD 窗口
    • 切换盘符:D: 即可;
    • dir 类似 ls
    • 切换到不通盘符下的目录:cd /d D:O1O-Code
    • cls 类似 clear
    • 创建文件夹 md
    • 移除文件夹 rd
    • 删除文件 del
    • ipconfig
    • mspaint 打开画图
    • calc 打开计算机

    P23 数据类型介绍

    • 字符 char 占 2 个字节,字符和字符串是有区别的;
    • boolean 占 1 位;
    • 1 字节 = 8 位

    p25 类型转换

    低 ---------------------------------------------------------------------------------->高
    byte(1字节),short(2字节),char(2字节)->int(4字节)->long(8字节)->float(4字节)->double(8字节)
    
    • 「强制转换」:高 -> 低,比如 int -> byte,a 为 int 类型,就需要 byte b = (byte)a;
    • 「自动转换」:低 > 高,比如 byte -> int,a 为 byte 类型,则仅需 int b = a;

    JDK7 新特性,数字之间可以用下划线分割,方便阅读:

    int money = 10_0000_0000;
    

    注意点:

    • 操作比较大的数字,注意溢出问题(可以先把计算公式中的一个数字类型强转为 long 型)

    P29 逻辑运算符、位运算符

    位运算的好处,计算效率高:

    0000 0010   2
    0001 0000   2*2*2*2
    
    • 2<<3 相当于 2*Math.pow(2,3)
    • 5<<2 相当于 2*Math.pow(2,2

    P30 三元运算符及小结

    字符串连接符:

    System.out.println("" + 10 + 20);  // 输出 1020
    System.out.println(10 + 20 + "");  // 输出 30
    

    三元运算符:x?y:z 如果 x 为真,则为 y,否则为 z;

    JavaDoc

    参数信息:

    • @author 作者
    • @version 版本
    • @since 指明需要最早使用的jdk版本
    • @param 参数名
    • @return 返回值情况
    • @throws 异常抛出情况

    快捷键:

    • 输入/**+Enter之后,直接生成 javaDoc 注释文档

    命令行生成 javaDoc:

    javadoc -encoding UTF-8 -charset UTF-8 Doc.java
    

    会生成 index.html

    更多标记,查阅:

    P33 用户交互 Scanner

    java.util.Scanner 类是 Java 5 开始提供的。

    Scanner s = new Scanner(System.in)
    ``
    获取输入的字符串:
    next:
    - `next()` 一定要读取到有效字符后,才可以结束输入;
    - 对输入有效字符之前遇到的空白,`next()` 方法将会自动将其去掉;
    - `next()` 不能得到带有空格的字符串
    
    nextLine():
    - 以 `Enter` 为结束符,`nextLine()` 方法返回的是输入回车之前的所有字符;
    
    - `hasNext()` 与 `hasNextLine()` 判断是否还有输入的数据;
    
    ## P37 流程控制:Switch 选择结构
    
    ```java
    switch(expression){
        case value:
            // 语句
            break;
        case value:
            // 语句
            break;
        default:
            // 语句
        
    }
    

    语法点:

    • 要注意 expressionvalue 的值类型
    • expression 有的教程中也称为 integral-selector——「整数选择因子」。它要求使用一个选择因子,并且必须是 byte/short/int/char 四种数据类型、枚举类型、String 类型(从 Java7 开始);
    • 枚举类型用来搭配 switch 工作,优雅;
    • case 标签后的 value 值也称为 integral-value,也可以是一个表达式;
    • default 标签是当前面没有匹配的 case 时,会进入执行;

    补充:

    .class 文件时字节码文件,需要反编译查看,编译结果可能在 target 目录下,或者打开 IDEA 的 Project Structure设置,查看 Project complier output 设置的路径,复制对应的 .class 文件到IDEA的目录下,可以实现反编译打开。
    经过反编译查看,可以发现当使用 String 作为表达式时,其实还是会转换成数字。

    P38 While 循环

    需要一个让表达式可以停止的操作;

    P45 方法

    方法的设计原则:方法的本意是功能块,最好保持方法的「原子性」,一个方法只完成 1 个功能,这样有利于日后的扩展和维护。

    • 形参:方法定义的变量;

    • 实参:调用方法时,传入的参数值;

    • Java 是值传递,不是引用传递;

    • 方法的重载就是在一个类中,有相同的函数名称,但是形参不同的方法;

      • 同名方法,参数的类型必须不同,返回值类型不做要求;

    直接编译 java 文件,例如 java Demo.java,会生成 Demo.class 文件。如果直接 java Demo 运行这个文件,会报错:错误: 找不到或无法加载主类,怎么解决这个问题呢?需要切换到包的路径的上一层去执行。

    P49 可变参数

    • 从 JDK 1.5 之后开始的,方法声明中,参数类型后加一个省略号 ...
    • 一个方法中,只能指定一个可变参数,它必须是方法的最后一个参数;
    • 其实就是存入了一个数组内;
        public static void add(int... numbers) {
            if (numbers.length == 0) {
                System.out.println("未输入求和数字!退出");
                return;
            }
            int sum = 0;
            for (int number : numbers) {
                sum = sum + number;
            }
            System.out.println(sum);
        }
    

    P50 递归 recursive

    • 递归:A 方法调用 A 方法本身!
    • 使用场景:想想数学中的归纳推理!
    • 递归利用了栈机制,效率并不一定高;

    递归结构主要包括两个部分:

    • 递归头:什么时候终止调用。如果没有停止的条件,将会陷入死循环 —— 边界条件
    • 递归体:什么时候需要调用方法自身;

    P51 数组 Array

    • 相同类型的数据的有序集;

    数组的创建:

    // 定义
    dataType[] arrayRefVar;
    //初始化,指定了数组的长度
    arrayRefVar = new dataType[arraySize];
    

    还可以:

    // 直接赋值了
    dataType[] arrayRefVar = new dataType[]{xx,...}
    

    还可以:

    // 省略new
    dataType[] arrayRefVar = {xx,...}
    

    Java 内存分析:

    • 堆:
      • 存放 new 的对象和数组;
      • 可以被所有线程共享,不会存放别的对象的引用
    • 栈:
      • 存放基本变量类型(会包含这个基本类型的具体数值);
      • 引用对象的变量(会存放这个引用在堆里面的具体地址)
    • 方法区:
      • 可以被所有的线程共享;
      • 包含了所有的class和static变量;

    数组的基本特点:

    • 数组的长度是确定的;
    • 元素类型相同;
    • 数组元素可以是任何类型;
    • 数组的变量属于引用类型;
    • 数组对象本身是在堆中的;

    Tips:

    • arrayName.for 快速生成 for each 循环;

    二维数组:

    // 类似于 2 行 5 列
    int[][] demo = new int[2][5]
    // 实例,类似 4 行 2 列
    int[][] array = {{1,2},{2,3},{3,4},{4,5}}
    

    P57 数组:Arrays 类讲解

    工具类 Arrays 提供了很多 static 方法供我们使用,方便对数组对象的操作。

    • Arrays.toString(arrayName) 打印数组 arrayName 中的每个元素;
    • Arrays.sort(arrayName) 对数组排序,方法无返回值,作用于数组对象本身;
    • Arrays.fill 填充方法,很多重载定义;

    P58 冒泡排序

    总共有 8 大排序。

    • 冒泡排序,两层循环,外层冒泡论述,里面依次比较;
    • 嵌套勋魂,可以得出这个算法的时间复杂度 O(n2)
    • 可以进一步优化

    P60 面向对象

    • 面向对象编程(Object-Oriented Programming,OOP
    • 面向对象编程的本质就是:以类的方式组织代码,以对象组织(封装)数据。类是对象的「模板」。

    三大特性:

    • 封装
    • 继承
    • 多态

    P63 类与对象的创建

    • 使用 new 关键字创建对象(类的实例)的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及类中构造器的调用;
    • 类中构造器也称为构造方法,在进行创建对象的时候必须被调用的。
    • 构造器有以下 2 个特点:
      • 必须和类同名;
      • 必须没有返回类型,也不能写 void

    P64 构造器详解

    • 无参构造方法:即使没有定义构造器,依然包含了一个无参构造方法;

    一个类如果没有显示地定义构造器方法,其实,默认包含无参的构造方法。编译器帮你自动做了这样的操作。比如一个 Person.java 类,编译好之后,对应生成的 Person.class 字节码文件中,其实是有如下的无参构造方法的:

        public Person() {
        }
    
    • 有参构造器:一旦定义了有参构造器,无参构造必须显示地定义!

    注意点:

    • 使用 new 关键字,必须要有构造器,本质需要调用构造器;
    • 构造方法主要用来初始化值;

    P65 创建对象内存分析

    • 粗略讲,对象真实存储在「堆」中,变量名本身存储在「栈」中。
    • 堆里面包含了方法区;

    P66 简单小结类与对象

    • 对象(实例)是通过引用看来操作的:栈中变量-->堆中对象;

    P67 面向对象:封装

    • 该露的露,该藏的藏
      • 「高内聚,低耦合」:高内聚就是类的内部数据操作细节自己完成;低耦合就是仅暴露少量方法给外部使用;
    • 封装:数据的隐藏
    • 简单一句话:「属性私有,get/set
    • private 私有

    封装的意义:

    • 提高程序的安全性,保护数据
    • 隐藏代码的细节
    • 系统可维护性增加了

    P68 继承

    • 关键字 extends
    • Java 中只有单继承,没有多继承!
    • 子类和父类之间,从意义上讲应该具有 is a 的关系,例如 Student is a Person
    • 子类不可以继承父类中 private 修饰的属性和方法;

    Tips:

    • Ctrl+H 查看继承关系;

    P69 Super 详解

    super 作用:

    • super 只能出现在子类的方法或者构造方法中;
    • super.name 子类调用父类中的属性
    • super.test() 子类中调用父类中的方法;
    • super() 调用了父类中的无参构造方法,这句话隐式包含在了子类的无参构造器中,并且,是第一行(也就是说,首先调用了父类的无参构造器,其次,再调用了子类本身的无参构造器)!

    注意点:

    • 父类中的 private 修饰的属性和方法,子类中还是无法被调用的;
    • super 和 this 不能同时调用构造方法
      • super() 调用父类的无参构造方法;
      • this() 调用本类中的的构造方法;

    P70 方法的重写

    重写:

    • 方法名必须相同;
    • 参数列表必须相同
    • 修饰符:范围可以扩大 public > protected > default > private
    • 抛出的异常:范围,可以被缩写,但不能扩大;

    例子:

    • 父类的引用指向了子类时:Father demo = new Son();
      • 调用了静态方法时,比如 demo.methodA(),加入这个 methodA 是静态方法,那么,即使子类中重写了这个方法,依然调用的是父类的方法;
      • 调用不是静态方法时,demo.methodB(),这时候就会调用子类中重写的这个方法;

    注意点:

    • 重写,仅和非静态方法有关!
    • private 方法不能被重写!

    P71 什么是多态

    • 同一方法可以根据发送对象的不同而采用多种不同的行为方式;
    • 一个对象的实际类型是确定的,但可以指定对象的引用的类型有很多;

    使用 new 创建出的对象的实际类型是确定的:

    • new Student()
    • new Person()

    指向对象的变量的引用类型不确定:

    • Student s1 = new Student()
    • Person s2 = new Student()

    s1、s2 能执行哪些方法,它们的引用类型是关键。比如 Student 类中比父类多定义了一个 say() 方法,s2 依然是无法调用 s2.say() 的,因为 Person 类没有该方法!

    Person s2 = new Student() 这样写的意义是什么呢?

    • 用父类规范了对象的行为,无法调用子类独有的方法!

    注意事项:

    • 多态是方法的多态!属性并没有多态!

    • 父类和子类有联系

    • 多态存在的条件:

      • 继承关系
      • 方法的重写(s1.run();s2.run(); 虽然可能都是 Person 的引用类型,但是实际对象可能一个是 Student对象,一个是 Teacher 对象)
      • 父类引用指向子类对象:Person aa = new Student(); Person bb = new Teacher(); 这里的 aa 类型就是 Person,但是会优先调用子类中重写的方法,如果没有重写,才调用父类中的方法;
    • static 方法属于类,它不属于实例,不能被重写!

    • private 方法私有的,也不能重写!

    P72 instanceof 和 类型转换

    instanceof 关键字用于判断 2 个类之间是否具有父子关系,例如 aa instanceof Person

    类型之间的转换:

    • 高(父)转低(子),需要强制转换 ——「向下转换」
    • 低(子)转高(父),自动转换,子类转换为父类,可能会丢失子类中自己的独有的一些方法:Person aa = new Student(); ——「向上转型」

    P73 static 关键字详解

    属于类,而不是对象(实例):

    • 静态属性
    • 静态方法
    • 静态代码库

    注意点:

    • 静态方法不能调用非静态的属性和方法,因为静态方法是随着类加载的;

    补充:

    • 匿名代码块是创建对象时调用的,在构造方法之前;
    • 静态代码块是在匿名代码块执行之前执行的,只执行一次
    • 匿名代码块中定义的变量属于局部变量,并不是类的属性!
    • 导入静态方法:import static java.lang.Math.random;

    P74 抽象 abstract

    • 定义抽象类,抽象类的子类都必须实现它的方法,除非它的子类也是抽象类;
    • 定义抽象方法,不定义方法体;

    注意点:

    • 不能 new 抽象类创建对象,但是通过 .class 文件可以发现,抽象类是有无参构造器的,说明有构造器不一定就能用 new 创建对象!
    • 抽象类中可以定义非抽象方法,所以,抽象类是一个不彻底的抽象!没有 interface 专业!
    • 抽象方法必须在抽象类中;

    抽象类存在的意义?

    • 提高开发效率,节省代码;

    P75 接口的定义与实现 interface

    • 接口只有规范,自己无法写方法 —— 相对于抽象类来讲,接口类似专业做规范的!约束和实现分离:面向接口编程~
    • 接口中的方法,缺省就是 public abstract 修饰的!
    • 接口中定义的属性,其实是一个常量,缺省是 public static final 修饰的!—— 所以实际项目中,常常也会通过接口定义一些常量~
    • 接口需要实现类,使用 implements 关键字定义实现类;
    • implements 可以实现多个接口,这就是比 extends 有优势的地方了,「多继承」的效果!
    • 子类需要重写接口中的方法!

    理解:

    • 接口就是规范,定义一组规则;
    • 接口的本质是契约,让它的子类去遵守;
    • OOP 的精髓,是对对象的抽象

    作用:

    • 约束,规范,契约
    • 定义一些方法,让人去实现;

    注意点:

    • 查看接口类对应的字节码文件,可以发现接口是没有无参构造器的!

    P76 N 种内部类

    • 内部类就是在一个类的内部再定义一个类
    • 内部类可以获得外部类的私有属性、私有方法!

    内部类的种类:

    • 成员内部类
    • 静态内部类
    • 局部内部类:在方法里定义一个类;
    • 匿名内部类:没有名字初始化一个对象,不用将实例保存到变量中(接口常用);

    P77 异常

    主要分为三种类型的异常:

    • 检查性异常:用户错误或问题引起的异常。这是程序猿无法预见的。
    • 运行时异常:运行时异常是可能被程序猿避免的异常。
    • 错误:错误不是异常,而是脱离程序猿控制的问题。例如,当栈溢出时(OutOfMemory),一个错误就发生了,它们在编译时是检查不到的。

    Java 异常体系结构:

    • Java 把异常当做对象处理,并定义一个基类 java.lang.Throwable 作为所有异常的超类;
    • 在 Java API 已定义了许多异常类,这些异常类分为两大类,错误 Error 和 异常 Exception

    Error:

    • Error 类对象由 Java 虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关;
    • Java 虚拟机运行错误(Java MachineError
    • 虚拟机试图执行应用时,如类定义错误(NoClassDefFoundError)、链接错误(LinkageError

    Exception:

    • Exception 分支中,有一个重要的子类 RuntimeException(运行时异常),它下面又定义了很多具体的异常子类:
      • NullPointerException:空指针异常;
      • MissResourceException:丢失资源
      • ClassNotFoundException:找不到类等异常
    • 这些异常一般由程序逻辑错误引起,应该从逻辑角度尽可能避免这类异常发生;

    Error 和 Exception 的区别:

    • Error 通常是灾难性的致命的错误,是程序无法控制和处理的,当出现这类异常时,Java 虚拟机一般会选择终止线程;
    • Exception 通常是可以被程序处理的,并且,应该在程序中尽可能的去处理这些异常;

    P78 异常处理机制

    • 抛出异常
    • 捕获异常
            try {
                System.out.println(1 / 0);
            } catch (ArithmeticException e) {
                System.out.println("算术异常 ArithmeticException: "+e.getMessage());
               // 打印错误的栈信息
                e.printStackTrace();
            } catch (Exception e) {
                System.out.println("漏网之鱼 Exception: " + e.getMessage());
                e.printStackTrace();
            } catch (Error e) {
                System.out.println("漏网之鱼 Error: " + e.getMessage());
                e.printStackTrace();
            } finally {
                System.out.println("END~");
            }
    

    主动抛出异常:

    • throw 关键字,throw new ArithmeticException("哎呀,计算出错了!"); 一般在方法中主动抛出异常;
    • throws 关键字,用在方法上,那么,使用该方法时,就需要主动利用 try catch 捕获,或者,继续向上抛出异常;

    注意点:

    • 异常的范围要逐级扩大,否则会报错,

    Tips:

    • 快捷功能 surround with 可以快速选中代码段上下生成相关片段,Win 快捷键 Ctrl+Alt+T,Mac 快捷键 Commadn+Option+T

    P79 自定义异常及经验小结

    • 自定义异常,可继承 Exception 类即可;

    经验总结:

    • 尽量去处理异常,切忌仅简单的调用 printStackTrace() 打印输出;
    • 在多重 catch 块后面,可以加一个 catch (Exception e) 来处理可能会被遗漏的异常;
    • 具体如何处理异常,需要结合具体的业务;
    • 尽量添加 finally 语句块去释放占用的资源;
  • 相关阅读:
    LeetCode: Number Complement
    LeetCode: Hamming Distance
    LeetCode: Sum of Left Leaves
    LeetCode: Ransom Note
    LeetCode: Minimum Moves to Equal Array Elements
    LeetCode: Linked List Random Node
    LeetCode: Product of Array Except Self
    LeetCode:Two Sum II
    LeetCode: Minimum Moves to Equal Array Elements II
    杂记 -- 时间段内应用程序调用次数限制
  • 原文地址:https://www.cnblogs.com/michael-xiang/p/12430958.html
Copyright © 2011-2022 走看看