参考资料

北京银行新员工培训-JAVA基础.pdf

《零基础学Java》翁恺,

菜鸟教程 https://www.runoob.com/java

毕向东-java视频https://www.bilibili.com/video/BV1Rt411f7F5?from=search&seid=2643401048507044977

尚硅谷视频

【书籍】:《Head First Java》

【进度】https://www.bilibili.com/video/BV1Rt411f7F5?p=101

【问题】

【笔记】

内存

image.png

:存储局部变量、对象的引用、基础数据类型。 数据使用完毕,会自动释放
堆:存储对象(字符串、数组)。
方法区(静态区):存储类定义、static变量与方法

JVM
https://www.ibm.com/support/knowledgecenter/zh/SSEP7J_10.2.2/com.ibm.swg.ba.cognos.ig_rtm.10.2.2.doc/t_jvm_cnfg.html
https://www.jianshu.com/p/d3a0b4e36c28

来一份常见 JVM 面试题+“答案”
https://www.jianshu.com/p/14018c414d8b

整个JVM内存大小=年轻代大小 + 年老代大小 + 持久代大小

-Xmx:能够使用的最大内存数,默认为物理内存的1/4

-Xms用来设置程序初始化的时候内存栈的大小,
增加这个值的话你的程序的启动性能会得到提高。
不过同样有前面的限制,以及受到-Xmx的限制。
默认为物理内存的1/64。

-Xmn:新生代大小,通过这个值也可以得到老生代的大小:-Xmx减去-Xmn
-Xss128k:设置每个线程的堆栈大小
-XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的大小比值。
设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6

-XX:NewRatio=n:设置年轻代和年老代的比值。(默认为2 ?)
如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4

-XX:+UseConcMarkSweepGC:设置并发收集器
-XX:MetaspaceSize、-XX:MaxMetaspaceSize:分别设置元空间最小大小与最大大小

-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64
XX:MaxPermSize设置最大非堆内存的大小默认是物理内存的1/4

收集器设置
-XX:+UseSerialGC:设置串行收集器
-XX:+UseParallelGC:设置并行收集器
-XX:+UseParalledlOldGC:设置并行老年代收集器
-XX:+UseConcMarkSweepGC:设置并发收集器
并行收集器设置
-XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数。并行收集线程数。
-XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间
-XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)

对象的创建

image.png

image.png

image.png

数组

方式一int[] arr=new int[n] ;arr[0]=1
方式二int[] arr=new int[] {1,2,3,4}
方式三 int[] arr={1,2,3,4}

数组也是一种对象。arr是引用变量。

如果没有引用变量指向 对象,那么这个对象会变成“垃圾”,最终会被JVM的垃圾清理器清理掉

两个引用变量指向同一个数组:
int[ ] x = new int[3];
int[ ] y = x ;

若执行y[1] = 100;
则x[1]也会变为100.
image.png

数组变量是数组的管理者而非数组本身,
数组变量之间的赋值是管理权限的赋予,
数组变量之间的比较是判断是否管理同一个数组。

常用类

String类

String是一个类,String的变量是对象的管理者而非所有者

equals()方法:判断是否相等
==:判断是否是同一个

访问字符串中的字符:s.charAt(index)方法

substring()方法:截取字符串中的一段
indexOf()方法:查找字符出现在字符串中的位置

Scanner类

可以通过 Scanner 类来获取用户的输入。
下面是创建 Scanner 对象的基本语法:
Scanners=newScanner(System.in)

StringBuffer 和 StringBuilder 类
和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。
由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。
类的定义:具有共同特性的对象的抽象

Object类:所有类的父类
toString():所有类都有toString(),返回当前对象的字符串表达。

equals() 应该使用常量或确定有值的对象来调用
substring()

String类和StringBuffer类的比较、选择使用

包装类
字符串和基本数据类型互转

包装类

数据类型:基本类型+引用类型
image.png

类型 初始值 范围
byte

| -128~127 | | short |

|

| | int | 0 |

| | long |

|

| | float | 0.0 |

| | double | 0.0 |

| | char |

|

| | boolean | false |

| |

|

|

| |

|

|

|

image.png

image.png

面向对象

面向对象:找(调用)专业的人(对象)做专业的事(执行方法 ),提高效率

引用变量(类类型变量)指向对象

多个引用指向同一个对象时,用任意一个 引用变量对对象进行操作、改变,
那么等到其他引用变量对对象进行操作时,对象已经不是最初的样子。

在Java中,引用类型的变量非常类似于C/C++的指针。引用类型指向一个对象,指向对象的变量是引用变量。
这些变量在声明时被指定为一个特定的类型,比如 Employee、Puppy 等。变量一旦声明后,类型就不能被改变了。
对象、数组都是引用数据类型
所有引用类型的默认值都是null。
一个引用变量可以用来引用任何与之兼容的类型。

封装

使用者对类内部定义的属性(对象的成员变量)的直接操作会导致数据的错误、混乱或安全性问题。

  1. class Animal {
  2. public int legs;
  3. public void eat(){
  4. System.out.println("Eating");
  5. }
  6. public void move(){
  7. System.out.println("Moving.");
  8. }
  9. }
  10. public class Zoo {
  11. public static void main(String args[]) {
  12. Animal xb = new Animal();
  13. xb.legs = 4;
  14. System.out.println(xb.legs);
  15. xb.eat();
  16. xb.move();
  17. }
  18. }


image.png

  1. class Animal {
  2. private int legs;// 将属性legs定义为private,只能被Animal类内部访问
  3. public void setLegs(int i) { // 在这里定义方法 eat() 和 move()
  4. if (i != 0 && i != 2 && i != 4) {
  5. System.out.println("Wrong number of legs!");
  6. return;
  7. }
  8. legs = i;
  9. }
  10. public int getLegs() {
  11. return legs;
  12. }
  13. }
  14. public class Zoo {
  15. public static void main(String args[]) {
  16. Animal xb = new Animal();
  17. xb.setLegs(4); // xb.setLegs(-1000);
  18. //xb.legs = -1000; // 非法
  19. System.out.println(xb.getLegs());
  20. }
  21. }

封装的优点
1. 良好的封装能够减少耦合。

  1. 类内部的结构可以自由修改。

  2. 可以对成员变量进行更精确的控制。
    4. 隐藏信息,实现细节。

私有属性,通过set()和get()方法访问

构造方法:给对应的对象进行初始化
类的构造方法:方法名与 类名 完全一致,类型为void;实例化时,必然会调用构造方法
构造代码块:给所有对象进行统一初始化

静态变量和静态方法

static静态变量、静态方法 :被多个对象共享
变量类型:实例变量、静态变量(类变量)、局部变量

类变量也称为静态变量,在类中以 static 关键字声明,但必须在方法之外。
静态变量可以通过:ClassName.VariableName的方式访问。存储在方法区

static变量的特点:
1、随着类的加载而加载(与成员变量不同:随着对象的创建而存在)
2、优先于对象存在
3、被所有对象共享
4、可以直接被类名调用
**

static变量与实例变量的区别:
1、存放于方法区(实例变量存放于 堆区)
2、生命周期长,随着类的消失而消失(实例变量随对象的消失而消失)

类变量被声明为 public static final 类型时,类变量名称一般建议使用大写字母

静态方法只能访问静态成员
静态方法中不可以定义this ,super关键字,因为静态优先于对象存在。

静态的利弊
利处:节省内存空间;可以直接被类调用
弊端:生命周期过长;访问出现局限性

什么时候使用static变量:当对象中出现共享数据(值)
什么时候使用static方法:当功能内部,没有访问到非静态数据(对象的特有数据),那么该功能可以定义为静态的。可以被继承,不能被重写

static的应用:工具类
https://www.bilibili.com/video/BV1Rt411f7F5?p=77

关键字final

image.png

继承

抽象类:含有抽象方法的类。不能实例化,必须被继承才能使用。一个类不能同时被 abstract 和 final 修饰
抽象方法:包含抽象方法的类,必须是抽象类。
构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法
抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。

final:final类不能被继承、final方法不能被重写

接口

接口就是规范,定义的是一组规则,体现了现实世界中“如果你是/要…则 必须能…”的思想。继承是一个”是不是”的关系,而接口实现则是 “能不能” 的关系。类似于“Like a”(区别于继承的 is a)。 接口是一种扩展功能,不是基础功能。
接口的本质是契约,标准,规范,就像我们的法律一样。制定好后大家都 要遵守。

接口(interface)是抽象方法和常量值定义的集合。
接口的特点:

  • 用interface来定义。
  • 接口中的所有成员变量都默认是由public static final修饰的。
  • 接口中的所有抽象方法都默认是由public abstract修饰的。
  • 接口中没有构造器。
  • 接口采用多继承机制。

实现接口的类,必须实现接口中的所有抽象方法。否则,仍为抽象类。

类与接口:实现关系。一个类可以实现多个接口(因为每个接口中的方法都是抽象的,不会出现冲突)
接口之间:继承关系

应用:代理模式
image.png

image.png

多态

image.png

一个引用类型变量如果声明为父类的类型,但实际引用的是子类 对象,那么该变量就不能再访问子类中添加的属性和方法。

  1. Student m = new Student();
  2. m.school = pku”; //合法,Student类有school成员变量
  3. Person e = new Student();
  4. e.school = pku”; //非法,Person类没有school成员变量
  5. //属性是在编译时确定的,编译时e为Person类型,没有school成员变量,因而编
  6. 译错误

方法声明的形参类型为父类类型,可以使用子类的对象作为实参调用该方法

  1. public class Test {
  2. public void method(Person e) {
  3. // ……
  4. e.getInfo();
  5. }
  6. public static void main(Stirng args[]) {
  7. Test t = new Test();
  8. Student m = new Student();
  9. t.method(m); // 子类的对象m传送给父类类型的参数e
  10. }
  11. }

image.png

从编译和运行的角度看:
重载,是指允许存在多个同名方法,而这些方法的参数不同。编译器根据方法不
同的参数表,对同名方法的名称做修饰。对于编译器而言,这些同名方法就成了
不同的方法。它们的调用地址在编译期就绑定了。Java的重载是可以包括父类
和子类的,即子类可以重载父类的同名不同参数的方法。
所以:对于重载而言,在方法调用之前,编译器就已经确定了所要调用的方法,
这称为“早绑定”或“静态绑定”;

而对于多态,只有等到方法调用的那一刻,解释运行器才会确定所要调用的具体
方法,这称为“晚绑定”或“动态绑定

image.png

Java修饰符

Java 修饰符:分为访问修饰符和非访问修饰符

可以使用访问控制符来保护对类、变量、方法和构造方法的访问。Java 支持 4 种不同的访问权限。
default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
public : 对所有类可见。使用对象:类、接口、变量、方法
protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)

image.png

非访问修饰符
为了实现一些其他的功能,Java 也提供了许多非访问修饰符。
static 修饰符,用来修饰类方法和类变量。
final 修饰符,用来修饰类、方法和变量,final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。
abstract 修饰符,用来创建抽象类和抽象方法。
synchronized 和 volatile 修饰符,主要用于线程的编程。

super
image.png

image.png

class Person {
    protected String name = "张三";
    protected int age;
    public String getInfo() {
        return "Name: " + name + "\nage: " + age; 
    } 
}

class Student extends Person {
    protected String name = "李四";
    private String school = "New Oriental";
    public String getSchool() {
        return school; }
    public String getInfo() {
        return super.getInfo() + "\nschool: " + school;
    }
}

public class StudentTest {
    public static void main(String[] args) {
        Student st = new Student();
        System.out.println(st.getInfo());
    }
}

image.png

重载与重写

java中重载重写(override)的区别详解
首先是重载,重载就是在同一个类当中有多个名称相同方法,但各个相同方法的参数列表不同(无关返回值类型)。如下,在test3中三个方法…

重写则发生在不同的类当中,并且两者要有继承关系,重写是方法名字和参数的列表是要完全一致的

方法的隐藏:用子类去调用方法(而非对象)时,会隐藏父类的类方法。此时方法前要加static

类的继承:实例化子类时,先调用父类的构造方法(默认调用父类无参的构造方法)

父类引用指向子类对象:Father s = new Son()
s.fangfa()此处调用子类的重写方法
system.out.printIn(s.bianliang)此处输出父类的变量,因为变量不允许重写

如果在子类中需要访问父类的同名变量,则super.变量名;访问本类中的变量,则this.变量名
如果子类重写方法时,需要引用父类中的方法,则super.方法

对象的交互(详见中国大学MOOC课程《零基础学Java》8.2.1,翁恺老师)
一个编译单元中,只能有一个类 是public的,源文件的名称应该和 public 类的类名保持一致

内部类

面向对象总结

异常处理

异常分类
image.png

image.png

先 抛(throw),后抓(try-catch-finally 或者throws)
throw是生成异常阶段,try和throws是处理异常阶段
image.png

异常处理的方式
方式一:try-catch-finally
方式二:throws + 异常类

处理方式一try-catch-finally

try{
    ...... //可能产生异常的代码
    }
catch( ExceptionName1 e ){
    ...... //当产生ExceptionName1型异常时的处置措施
    }
catch( ExceptionName2 e ){
    ...... //当产生ExceptionName2型异常时的处置措施
    }[ finally{
    ...... //无论是否发生异常,都无条件执行的语句
} ]

image.png

处理方式二 throws

如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何处理这 种异常,则此方法应显示地声明抛出异常,表明该方法将不对这些异常进行处理, 而由该方法的调用者负责处理

image.png

手动throw

throw可以自动进行,也可以手动进行。
image.png


用户自定义异常

一般地,用户自定义异常类都是RuntimeException的子类。
 自定义异常类通常需要编写几个重载的构造器。
 自定义异常需要提供serialVersionUID
 自定义的异常通过throw抛出。
 自定义异常最重要的是异常类的名字,当异常出现时,可以根据
名字判断异常类型。

image.png

image.png

image.png

截止p.125
对捕获到的异常对象进行常见方法操作:
String getMessage()获取异常信息
void printStackTrace()

功能方法上抛出异常(throws)后,调用者 必须对其进行捕获或者继续 抛出

自定义异常:在功能方法中 手动通过throw抛出一个自定义异常。throw new xxException()

throw与throws的区别:
throws用于函数上,throw用于函数内
throws后面跟的是异常类,throws后面跟的是异常对象

特殊的子类异常:RuntimeExcption
如在函数内throw该异常,则函数上可以不用声明,便可通过编译
如果函数上声明了,调用者也不必进行处理

自定义异常时,如果该异常的发生,无法再继续进行运算,
就让自定义异常继承RuntimeException

多线程

p.130-p.154

进程与线程
一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。多线程能满足程序员编写高效率的程序来达到充分利用 CPU 的目的。

进程:一个进程包括由操作系统分配的内存空间,包含一个或多个线程。

一个线程不能独立的存在,它必须是进程的一部分。
一个进程一直运行,直到所有的非守护线程都结束运行后才能结束。

连接数据库

image.png

连接MYSQL

image.png

代码样例:D:\IdeaProjects\MysqlTest\src\com\test
参考:
文档https://www.runoob.com/java/java-mysql-connect.html
视频https://www.bilibili.com/video/BV1eE411C7bJ?p=36
image.png

执行DDL和DML,用stat.executeUpdate(sql)
执行DQL,使用stat。executeQuery(sql)

IO流

序列化
步骤:
1创建出FileOutputStream
2创建出ObjectOutputStream
3写入对象
4关闭ObjectOutputStream
能实现序列化的前提条件:实现Serialization

网络编程
多线程