配置环境

我的 JDK 文件夹如下:

  • jdk1.8.0_351【JAVA 8】
  • jdk-11.0.17【JAVA 11】
  • jdk-17.0.5【JAVA 17】
  • JRE_1.8.0
# 测试是否切换成功
java -version
javac -version

获取 JDK

① 点击下载 jdk-8uxxx-windows-x64.exe 那个即可,安装时 JDK 8JRE 8 的路径都放在 JDK 文件夹中
② 然后打开环境变量,新建变量 JAVA_HOME,变量值为 D:\Software\JDK\jdk1.8.0_351bin 的父目录)
③ 最后配置 Path,首先删除 C:\XXX\Oracle\Java\javapath(如果已有的话),再添加 %JAVA_HOME%\bin 并移动到最顶部

推荐下载的有 JAVA 11JAVA 17,配置操作和上面基本一致

简述编译过程

JAVA 可以看作编译性语言,也可以看作解释性语言,原因如下:

// test.java
// 主类必须和文件名一致
public class test {  
    public static void main(String args[]){  
        System.out.println("筱团");  
    }  
}  

先经过整体代码的编译(生成 test.class),此时一行报错,就会编译失败

>>> javac test.java

再进行解释器的逐步解释(显示输出内容),此时一行报错,只会显示错误语句的位置

>>> java test
"筱团"

JAVA 基础

前置知识

  • 一个 java 文件最多有一个 public 类,且此类名与文件名一致
  • java 代码有 switch .. case 语句、 do .. while 语句和 try .. catch 语句

类的介绍

package 包名(当前文件夹名称)
import 包名.类名(其他文件夹,该文件夹下的类名)

修饰符 返回值类型 方法名(参数类型 参数名){
    ...
    方法体
    ...
    return 返回值;
}

类的修饰符:

  • public,公共(任何人都能够调用包中的类)
  • default,只能在当前包中被调用

类成员修饰符

  • public,公共,所有的只要有访问类,类中的成员都可以访问到
  • private,私有,只允许自己类调用
  • protected,同一个包 或 子类可以调用(这个子类包括非同一个包,外部继承包内的子类)
  • default,只能在同一个包内访问

非访问修饰符(defaultstaticfinalabstractsynchronizedvolatile

静态成员

class A {
    // 非静态成员
    public void func1() {
        System.out.println("func1");
    }

    // 静态成员
    public static void func2() {
        System.out.println("func2");
    }
}

public class test {
    public static void main(String[] args) {
        // 非静态成员,需要实例化,才能调用
        A object = new A();
        object.func1();

        // 静态成员,可以直接调用
        A.func2();
    }
}

输入输出

import java.util.Scanner;

public class test {
    public static void main(String[] args) {
        // 输入
        Scanner input = new Scanner(System.in);
        String text = input.nextLine();

        // 输出
        System.out.println(text);
    }
}

数据类型

JAVA 全部的基本数据类型有 8 个:

  • byte,取值范围:-128 ~ 127
  • short,取值范围:-32768 ~ 32767
  • int,取值范围:-2147483648 ~ 2147483647
  • long,取值范围:-9223372036854774808 ~ 9223372036854774807
  • float,取值范围:1.401298e-45 ~ 3.402823e+38
  • double,取值范围:4.9000000e-324 ~ 1.797693e+308
  • char,取值范围:0 ~ 65535
  • boolean,取值范围:true or false

下面演示字节数组和字符串之间的转换(JAVA 中字节的范围:-128 ~ 127)

import java.util.Arrays;

public class test {
    public static void main(String[] args) {
        // 字节数组 转 字符串
        byte[] dataList = {120, 105, 97, 111, 116, 117, 97, 110};
        String dataString = new String(dataList);
        System.out.println(dataString); // 打印 xiaotuan

        // 字符串 转 字节数组
        String dataString2 = "xiaotuan";
        byte[] dataList2 = dataString2.getBytes();
        System.out.println(Arrays.toString(dataList2)); // 打印 [120, 105, 97, 111, 116, 117, 97, 110]
    }
}

字符串操作

// 字符
char object = 'x';
// 字符串
String object2 = "xiaotuan";
String object3 = new String("xiaotuan");
String object4 = new String(new byte[]{120, 105, 97, 111, 116, 117, 97, 110});

// 获取指定位置字符
char object5 = object2.charAt(0);
// 获取字符串长度
int object6 = object2.length();
// 去除字符串前后空格
String object7 = object2.trim();
// 小写
String object8 = object2.toLowerCase();
// 大写
String object9 = object2.toUpperCase();
// 分割
String[] object10 = object2.split("t"); // xiao uan
// 切片,相当于 python 的 [2:4]
String object11 = object2.substring(2, 4);
// 替换
String object12 = object2.replace("x", "X");
// 判断是否相等
boolean object13 = object2.equals(object3);
// 判断是否包含
boolean object14 = object2.contains("xiao");
// 判断是否以目标字符串开头
boolean object15 = object2.startsWith("xiao");
// 字符串拼接
String object16 = object2.concat("zi");

// StringBuilder / StringBuffer 线程安全
StringBuilder sb = new StringBuilder();
// 字符串拼接
sb.append("xiaotuan");
// StringBuffer 转 String
String dataString = sb.toString();

数组

// 定义一维度数组
int[] data = new int[10];
int[] data = new int[]{1, 2, 3, 4, 5};
int[] data = {1, 2, 3, 4, 5};

// 打印一维度数组(三种方法)
System.out.println(Arrays.toString(data));

for (int i = 0; i < data.length; i++) {
    System.out.println(data[i]);
}

for (int a : data)
    System.out.println(a);

// 定义二维数组
int[][] data = {
        {16, 3, 2, 13},
        {5, 10, 11, 8},
        {9, 6, 7, 3}
};

// 打印二维度数组
System.out.println(Arrays.deepToString(data));

object 和 interface

JAVA 中所有的类都继承 Object

// 数组中可以是不同类型
Object[] object = new Object[3];
object[0] = 123;
object[1] = "xiaotuan";

// 同理,也可以这么写
List object1 = new ArrayList();
List object2 = new LinkedList();
Object object3 = new ArrayList();
Object object4 = new LinkedList();
// 约束,使得继承它的类必须含有内部方法
interface Aoo {
    public int run(String variable);
}

class Boo implements Aoo {
    public int run(String variable) {
        return 123;
    }
}

class Coo implements Aoo {
    public int run(String variable) {
        return 456;
    }
}

JAVA 高级

List 系列

最重要的是 List 存储的数组是可变的

  • ArrayList,连续的内存地址的存储(内部自动扩容)
  • LinkedList,底层基于链表实现(链表)
// ArrayList,默认内存存放的是混合数据类型

// 可以存放任意数据类型
ArrayList data1 = new ArrayList();
ArrayList<Object> data2 = new ArrayList<Object>();
// 约束只能存放 String 数据类型
ArrayList<String> data3 = new ArrayList<String>();

// 添加值
data3.add("xiao");
data3.add("tuan");

// 对数组元素进行操作
// 循环打印数组元素值
for (String item : data3) {
    System.out.println(item);
}

// 获取索引位置值
String value = data3.get(1);
/*
如果数组类型为 Object,那么返回值需要强制类型转换
String value = (String)data.get(1);
*/

// 设置索引位置值
data3.set(0, "Xiao");

// 删除索引位置值 / 选定值
data3.remove("tuan");
data3.remove(0);

// 获取数组长度
int size = data3.size();

// 判断是否包含目标字符串
boolean exist = data3.contains("xiao");
// LinkedList 和 ArrayList 是非常相似的

// 声明字符串数组
LinkedList<String> data = new LinkedList<String>();

// 从前面添加数组元素值(新增)
data.push("tuan");
data.addFirst("xiao");
ArrayList<String> data = new ArrayList<String>();
data.add("xiao");
data.add("tuan");

// 迭代器
Iterator it = data.iterator();
while (it.hasNext()) {
    String item = (String) it.next();
    System.out.println(item);

Set 系列

  • HashSet,去重,无序
  • TreeSet,去重,内部默认排序(ASCIIUnicode
// HashSet 和 TreeSet 非常相似,就以 HashSet 举例
// 对数组元素进行操作,与 List 系列基本类似

// 第一种添加变量的方法
HashSet<String> object1 = new HashSet<String>();
object1.add("xiao");
object1.add("tuan");

// 第二种添加变量的方法
HashSet<String> object2 = new HashSet<String>() {
    {
        add("xiao");
        add("tuan");
    }
};

// 取交集(注意这种方法会改变 object1 中的元素集合)
object1.retainAll(object2);

// 取并集(注意这种方法会改变 object1 中的元素集合)
object1.addAll(object2);

// 取差集(object1 - object2)
object1.removeAll(object2);

Map 系列

  • HashMap,无序
  • TreeMap,默认根据 key 排序
// HashMap 和 TreeMap 非常相似,就以 HashMap 举例
// 对键值元素进行操作,与 List 系列部分类似

// 第一种添加变量的方法
HashMap<String, String> object1 = new HashMap<String, String>();
object1.put("zi", "you");
object1.put("xiao", "tuan");

// 第二种添加变量的方法
HashMap<String, String> object2 = new HashMap<String, String>() {
    {
        put("zi", "you");
        put("xiao", "tuan");
    }
};

// 获取键对应的值
String value = object1.get("xiao");

// 判断是否包含某个键 / 值
boolean existKey = object1.containsKey("xiao");
boolean existValue = object1.containsValue("tuan");

// 循环(第一种方法)
Set<Map.Entry<String, String>> loop1 = object1.entrySet();
Iterator it1 = loop1.iterator();
while (it1.hasNext()) {
    Map.Entry<String, String> entry = (Map.Entry<String, String>) it1.next();
    String key1 = entry.getKey();
    String value2 = entry.getValue();
}

// 循环(第二种方法)
Set loop2 = object1.entrySet();
Iterator it2 = loop2.iterator();
while (it2.hasNext()) {
    Map.Entry entry = (Map.Entry) it2.next();
    String key2 = (String) entry.getKey();
    String value2 = (String) entry.getValue();
}

// 循环(第三种方法)
for (Map.Entry<String, String> entry : object1.entrySet()) {
    String key3 = entry.getKey();
    String value3 = entry.getValue();
}

// 循环(第四种方法,键对应的值并不都是 String)
for (Object entry : object1.entrySet()) {
    Map.Entry<String, Object> entryMap = (Map.Entry<String, Object>) entry;
    String key4 = entryMap.getKey();
    Object value4 = entryMap.getValue();
    if (value4 instanceof Integer) {
        System.out.println("数字:" + Integer.toString((Integer) value4));
    } else if (value4 instanceof String) {
        System.out.println("字符串:" + (String) value4);
    } else {
        System.out.println("未知类型:" + value4.toString());
    }
}

类和对象

class Person {
    // 静态变量
    public static String nickname = "tuanzi";

    // 实例变量
    public String name;
    public Integer age;

    // 构造方法
    public Person(String name, Integer number) {
        this.name = name;
        this.age = number;
    }

    // 绑定方法
    public void showInfo() {
        System.out.println("绑定方法");
    }

    // 静态方法
    public static void showData() {
        System.out.println("静态方法");
    }
}

public class test {
    public static void main(String[] args) {
        // 调用静态变量
        System.out.println(Person.nickname);
        // 创建对象
        Person people = new Person("xiaotuan", 20);
        // 调用实例变量
        System.out.println(people.name);
        System.out.println(people.age);
        // 调用静态方法
        Person.showData();
        // 调用绑定方法
        people.showInfo();
    }
}

继承

单继承

class Father {
    public String name;
    public Integer age;

    public Father(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public void Hello(String object) {
        System.out.println("Hello" + object);
    }
}

class Son extends Father {
    public Son(String name, Integer age) {
        super(name, age);
    }

    public void getInfo() {
        System.out.println(this.name + String.valueOf(this.age));
    }

    // 重写添加 @Override,编译器会判断形参是否与父类一致
    @Override
    public void Hello(String object) {
        System.out.println("Yoho" + object);
    }
}

实现多个接口

interface Father {
    public void walk();
}

interface Mother {
    public void run();
}

class Son implements Father, Mother {
    public void walk() {
        System.out.println("walk");
    }

    public void run() {
        System.out.println("run");
    }
}

抽象类和抽象方法

abstract class Father {
    // 抽象方法(约束子类必须要有这个方法)
    public abstract void Play(String object);

    // 普通方法
    public void Hello() {
        System.out.println("Hello");
    }
}

class Son extends Father {
    public void Play(String object) {
        System.out.println("I will play with you");
    }
}

JAVA 进阶

  • JAVA 常见加密