Java学习记录

66 阅读10分钟

安装开发环境

JDK8

卸载JDK

卸载JDK 1.删除java的安装目录 2.删除JAVA HOME 3.删除path下关于Java的目录 4.java-version

安装JDK

Java Archive Downloads - Java SE 8 (oracle.com)

运行编译

编译命令

javac Hello.java
java Hello

JVM 工作流程

image.png

包 package

包允许将类组合成较小的单元(类似文件夹),它基本上隐藏了类,并避免了名称上的冲突。包允许在更广泛的范围内保护类、数据和方法。你可以在包内定义类,而在包外的代码不能访问该类。这使你的类相互之间有隐私,但不被其他世界所知。

包的 3 个作用如下:

  1. 区分相同名称的类。
  2. 能够较好地管理大量的类。
  3. 控制访问范围。

Java 中使用 package 语句定义包,package 语句应该放在源文件的第一行,在每个源文件中只能有一个包定义语句,并且 package 语句适用于所有类型(类、接口、枚举和注释)的文件。定义包语法格式如下:

package 包名;

Java 包的命名规则如下:

  • 包名全部由小写字母(多个单词也全部小写)。
  • 如果包名包含多个层次,每个层次用“.”分割。
  • 包名一般由倒置的域名开头,比如 com.baidu,不要有 www。
  • 自定义包不能 java 开头。

使用 import 导入单个类的语法格式如下:

import 包名+类名;

上面语句用于直接导入指定类,例如导入前面的 example.Test 类,代码如下:

import example.Test;

使用 import 语句导入指定包下全部类的用法按如下:

import example.*;

上面 import 语句中的星号(*)只能代表类,不能代表包,表明导入 example 包下的所有类。

数据类型(八种基本数据类型 + 四种引用数据类型)

  • 位(bit): 又名 比特位,表示二进制位,是计算中内部数据储存的最小单位。一个二进制位只能表示0和1两种状态。
  • 字节(byte): 是计算机中处理数据的基本单位。一个字节等于八位(1Byte = 8bit)
  • 字(word): 计算机进行数据处理时,一次存取、加工和传送的数据长度。在常见的计算机编码格式下,一个字等于两个字节(十六位)(1word = 2Byte = 16bit)

JAVA中的数据类型分为两大类:

  • 基本数据类型:整型、浮点型、字符型、布尔型 整数类型 —— byte、short、int、long, 浮点类型 —— float、double 字符类型 —— char 布尔类型 —— boolean
  • 引用数据类型:接口(interface)、数组([ ])、类(class)。

数据类型转换:

转化从低级到高级:byte,short,char(三者同级)—> int —> long—> float —> double 1、低级转换高级:自动类型转换 2、高级转换低级:强制类型转换

int a = 3;
double b = 5.0;
a = (int)b;

static 关键字

  • static 关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就 可以通过类名去进行访问。
  • 静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时 会被初始化。
  • 能通过 this 访问静态成员变量吗?所有的静态方法和静态变量都可以通过对象访问 (只要访问权限足够)。
  • static 是不允许用来修饰局部变量

final

  • 可以声明成员变量、方法、类以及本地变量
  • final 成员变量必须在声明的时候初始化或者在构造器中初始化,否则就会报编译错误
  • final 变量是只读的
  • final 申明的方法不可以被子类的方法重写
  • final 类通常功能是完整的,不能被继承
  • final 变量可以安全的在多线程环境下进行共享,而不需要额外的同步开销
  • final 关键字提高了性能,JVM 和 Java 应用都会缓存 final 变量,会对方法、变量及 类进行优化
  • 方法的内部类访问方法中的局部变量,但必须用 final 修饰才能访问

ArrayList

ArrayList 本质上是一个动态数组,第一次添加元素时,数组大小将变化,不断添加元素后,会进行扩容。删除元素时,会按照位置关系把数 组元素整体(复制)移动一遍。

方法

类似函数,用来完成特定功能的代码片段

  • 修饰符: 修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
  • 返回值类型 : 方法可能会返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType 是关键字void
  • 方法名: 是方法的实际名称。方法名和参数表共同构成方法签名。
  • 参数类型: 参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
  • 方法体: 方法体包含具体的语句,定义该方法的功能。

image.png

  /*
    public static void main(String[] args)
    
    public:权限修饰符,权限最大,可选。
    static:静态方法,随着(Hello)类的加载而加载,消失而消失。
    void:  没有返回值
    main: 不是关键字,但是是一个特殊的单词,可以被JVM识别,且是主函数特有的。
    (String[] args):定义了一个字符串数组参数
    */
    
public class Hello{
    public static void main(String[] args){
        System.out.print("Hello world!");
    }
}

方法的重载

方法的重载的规则:

  • 方法名称必须相同。
  • 参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等)。
  • 方法的返回类型必湘同也可以不相同。
  • 仅仅返回类型不同不足以成为方法的重载。

值传递与引用传递

  • 值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数
  • 引用传递是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

内存分析

  • 方法区

数组

//静态初始化:创建+赋值
int[] a ={1,2,3,4,5};
//动态初始化:包含默认初始化
int[] b = new int[10];
b[0] = 10;
​
//二维数组
 int[][] array ={{1,2},{2,3},{3,4},{4,5}};
​
//打印数组元素Arrays.toString
 System.out.println(Arrays.toString(a));

数组的四个基本特点

  • 其长度是确定的。数组一旦被创建,它的大小就是不可以改变的。
  • 其元素必须是相同类型,不允许出现混合类型。
  • 数组中的元素可以是任何数据类型,包括基本类型和引用类型。
  • 数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。
  • 数组本身就是对象,Jva中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的
public class ArrayDemo02 {
    public static void main(String[] args) {
        int [] arrays ={1,2,3,4,5};
​
        //JDK1.5,没有下标
        for(int array : arrays){
            System.out.println(array);
        }
    }
}

面向对象

类的定义:

public class 类名{
    //属性
    //方法
}

类和对象的关系:

  • 类是对象的抽象
  • 对象是类的实例化

创建对象:

//类名 对象名 = new 类名();
Person person = new Person();

类的封装

封装(数据的隐藏)

  • 通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。
  • 属性私有,get/set

继承

JAVA中类只有单继承,没有多继承

  • object类
  • super
  • 方法重写

super

public class Student extends Person{
    /**
     * super注意点
     * 1.super调用父类的构造方法,必须在构造方法的第一个
     * 2.super 必须只能出现在子类的方法或者构造方法中
     * 3.super和this不能同时调用构造方法
     */
    private String name="person";
    public void test(String name){
        System.out.println(super.name);
    }
​
}

方法重写

在子类中如果创建了一个与父类中相同名称、相同返回值类型、相同参数列表的方法,只是方法体中的实现不同,以实现不同于父类的功能,这种方式被称为方法重写(override),又称为方法覆盖。

需要有继承关系,子类重写父类的方法!

重写都是方法的重写,和属性无关

  1. 方法名必须相同

  2. 参数列表列表必须相同

  3. 修饰符:范围可以扩其但不能缩小:public>Protected>Default>private

  4. 抛出的异常:范围,可以被缩小,但不能扩大:ClassNotFoundException-->Exception(大)

  5. 重写,子类的方法和父类必要一致:方法体不同!

    为什么需要重写: 父类的功能,子类不一定需要,或者不一定满足

内部类

可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。包括:成员内部类、局部内部类、匿名内部类和静态内部类

  • 内部类 可以 访问 外部类 当中的成员
  • 外部类 不能 直接访问 内部类 当中的成员
public class Outer {
    private int id =10;
    public void out(){
        System.out.println("outer 方法");
    }
​
    public class Inner{
        /**通过外部类来实例化内部类~
         * 获取外部类的私有属性
         */
​
        public void in(){
            System.out.println("Inner 方法");
        }
​
        public void getID(){
            System.out.println(id);
        }
    }
}

抽象类abstract

public abstract class Action{
    //1.抽象方法,只有方法名字,没有实现
    //2.不能new这个抽象类,只能靠子类去实现它
    //3.抽象类中可以写普通的方法
    //4.抽象方法必须在抽象类中
    public abstract void doSomething();
    
}

接口

  • 普通类:只有具体实现
  • 抽象类:具体实现和规范(抽象方法)都有!
  • 接口:只有规范!自己无法写方法~
  • 实现了接口的类,就需要重写接口中的方法
  • 实现多继承
//UserService
public interface UserService {
    //接口中所有定义其实都是抽象的 public abstract
    //    void run();
    void add(String name);
    void delete(String name);
    void update(String name);
    void query(String name);
}
​
//UserServiceImpl/**
 * 作用
 * 1.约束
 * 2.定义一些方法
 * 3.方法 public abstract
 * 4.常量 public static final
 * 5.接口不能被实例化,接口没有构造方法
 * 6.implements 可以实现多个接口
 * 7.必须要重写接口中的方法
 */
public class UserServiceImpl implements UserService,TimeService {
    @Override
    public void add(String name) {
​
    }
​
    @Override
    public void delete(String name) {
​
    }
​
    @Override
    public void update(String name) {
​
    }
​
    @Override
    public void query(String name) {
​
    }
}

快捷键

alt+ insert 生成constructor
Ctrl +h 继承树

异常

image.png

image.png

异常处理五个关键字

  • try
  • catch
  • finally
  • throw
  • throws
 try {
            System.out.println(a/b);
​
        }catch (ArithmeticException e){
            System.out.println("程序出现异常,变量b不能为0");
        }finally {
            System.out.println("finally");
        }
​
//throw new ArithmeticException();

Java 线程

  • 进程
  • 线程
  • 多线程

main函数是主线程

三种创建方式

image.png

public class TestThread1 extends Thread{
    @Override
    public void run() {
        //run 方法线程体
        for (int i = 0; i < 20; i++) {
            System.out.println("我在看代码--"+i);
        }
    }
​
    public static void main(String[] args) throws InterruptedException {
        //main 主线程
​
        //创建一个线程对象
        TestThread1 testThread1 =new TestThread1();
​
        //调用start()方法开启线程
        testThread1.start();
        Thread.sleep(1000);
        for (int i = 0; i < 20; i++) {
            System.out.println("我在学习多线程--"+i);
        }
​
    }
}

并发

多个线程同时操作同一对象

线程5大状态

image.png