Java基础笔记(小白友好版)

Java基础笔记(小白友好版)

1. Java简介

  • Java是一种广泛使用的计算机编程语言,由詹姆斯·高斯林(James Gosling)在1995年创建
  • Java的口号是"一次编写,到处运行"(Write Once, Run Anywhere)
  • Java程序需要先编译成字节码(.class文件),然后在Java虚拟机(JVM)上运行
  • 主要特点:
    • 面向对象:一切皆对象,代码更清晰易懂
    • 平台无关性:可以在Windows、Mac、Linux等不同系统上运行相同代码
    • 简单性:相比C++,去除了指针等复杂特性
    • 安全性:运行在虚拟机沙箱环境,更安全
    • 多线程:可以同时执行多个任务

2. 开发环境搭建

  • 安装JDK(Java Development Kit):去Oracle官网下载并安装
  • 配置环境变量:设置JAVA_HOME和PATH变量
  • 选择一个IDE(集成开发环境):
    • Eclipse:免费开源
    • IntelliJ IDEA:功能强大(有免费社区版)
    • VS Code:轻量级
  • Hello World示例:
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

3. 基本语法

  • 大小写敏感Hellohello是不同的
  • 类名:首字母大写,如StudentCar
  • 方法名:首字母小写,如getName()calculateTotal()
  • 源文件名:必须和公共类名相同,如类名为Student,则文件名为Student.java
  • 主方法入口public static void main(String[] args),程序从这里开始执行
  • 注释
    • 单行注释:// 这是单行注释
    • 多行注释:/* 这是多行注释 */
    • 文档注释:/** 这是文档注释 */

4. 数据类型

基本数据类型(8种)

  • 整型
    • byte:8位,范围-128到127,适合小范围数值
    • short:16位,范围-32768到32767
    • int:32位,范围约±21亿,最常用的整数类型
    • long:64位,范围更大,使用时加L,如long num = 100L;
  • 浮点型
    • float:32位,单精度,使用时加F,如float num = 3.14F;
    • double:64位,双精度,默认小数类型,如double num = 3.14;
  • 字符型
    • char:16位,表示单个字符,用单引号,如char c = 'A';
  • 布尔型
    • boolean:表示真或假,只有truefalse两个值

引用数据类型

  • :如StringStudent等自定义类
    String name = "张三";
    
  • 接口:定义行为的抽象类型
  • 数组:同类型数据的集合
    int[] numbers = {1, 2, 3, 4, 5};
    

5. 变量

  • 局部变量:方法内部定义的变量,只在方法内可见
    public void method() {
        int localVar = 10; // 局部变量
    }
    
  • 实例变量(非静态变量):属于对象的变量,每个对象有独立的副本
    public class Student {
        String name; // 实例变量
    }
    
  • 类变量(静态变量):属于类的变量,所有对象共享一个副本
    public class Student {
        static String school = "清华大学"; // 类变量
    }
    
  • 常量:使用final关键字,通常全大写
    final double PI = 3.14159;
    

6. 修饰符

访问修饰符

  • public:公共的,任何地方都可以访问
  • private:私有的,只能在当前类内访问
  • protected:受保护的,同包和子类可以访问
  • default(不写):同包内可以访问

例子:

public class Person {
    public String name;     // 公共变量,任何地方都可访问
    private int age;        // 私有变量,只有本类内可访问
    protected String home;  // 受保护变量,本包和子类可访问
    String hobby;           // 默认访问权限,只有本包内可访问
    
    public void speak() {   // 公共方法
        System.out.println("我是" + name);
    }
    
    private void think() {  // 私有方法
        System.out.println("思考中");
    }
}

非访问修饰符

  • static:静态的,属于类而非对象
  • final:最终的,不能被修改
  • abstract:抽象的,不能被实例化
  • synchronized:同步的,用于多线程安全
  • volatile:易变的,用于多线程可见性

7. 运算符

  • 算术运算符

    • 加:+,如int sum = 5 + 3; // 结果为8
    • 减:-,如int diff = 5 - 3; // 结果为2
    • 乘:*,如int product = 5 * 3; // 结果为15
    • 除:/,如int division = 5 / 2; // 结果为2(整数除法)
    • 取余:%,如int remainder = 5 % 2; // 结果为1
    • 自增:++,如count++++count
    • 自减:--,如count----count
  • 关系运算符

    • 等于:==,如if(a == b)
    • 不等于:!=,如if(a != b)
    • 大于:>,如if(a > b)
    • 小于:<,如if(a < b)
    • 大于等于:>=,如if(a >= b)
    • 小于等于:<=,如if(a <= b)
  • 逻辑运算符

    • 与:&&,两边都为true时结果为true
    • 或:||,有一边为true时结果为true
    • 非:!,取反,true变false,false变true
  • 赋值运算符

    • 简单赋值:=,如int a = 5;
    • 复合赋值:+=-=*=/=%=,如a += 2等同于a = a + 2
  • 三元运算符:条件 ? 值1 : 值2

    int max = (a > b) ? a : b; // 如果a>b,max为a;否则为b
    

8. 控制流

条件语句

  • if语句

    if (age >= 18) {
        System.out.println("成年人");
    }
    
  • if-else语句

    if (score >= 60) {
        System.out.println("及格");
    } else {
        System.out.println("不及格");
    }
    
  • if-else if-else语句

    if (score >= 90) {
        System.out.println("优秀");
    } else if (score >= 60) {
        System.out.println("及格");
    } else {
        System.out.println("不及格");
    }
    
  • switch语句

    switch (day) {
        case 1:
            System.out.println("星期一");
            break;
        case 2:
            System.out.println("星期二");
            break;
        // 其他情况...
        default:
            System.out.println("输入有误");
    }
    

循环语句

  • for循环:适用于知道循环次数的情况

    for (int i = 0; i < 5; i++) {
        System.out.println(i); // 打印0到4
    }
    
  • while循环:先判断后执行

    int i = 0;
    while (i < 5) {
        System.out.println(i);
        i++;
    }
    
  • do-while循环:先执行后判断,至少执行一次

    int i = 0;
    do {
        System.out.println(i);
        i++;
    } while (i < 5);
    

分支语句

  • break:跳出整个循环

    for (int i = 0; i < 10; i++) {
        if (i == 5) {
            break; // 当i等于5时跳出循环
        }
        System.out.println(i);
    }
    
  • continue:跳过本次循环

    for (int i = 0; i < 10; i++) {
        if (i == 5) {
            continue; // 当i等于5时跳过这次循环
        }
        System.out.println(i);
    }
    
  • return:返回方法结果,结束方法

    public int add(int a, int b) {
        return a + b; // 返回a+b的值,并结束方法
    }
    

9. 面向对象编程

类和对象

  • :是对象的模板,定义对象的属性和方法
  • 对象:是类的实例,代表具体事物

示例:

// 定义一个学生类
public class Student {
    // 属性(成员变量)
    String name;
    int age;
    
    // 方法
    public void study() {
        System.out.println(name + "正在学习");
    }
    
    public void showInfo() {
        System.out.println("姓名:" + name + ",年龄:" + age);
    }
}

// 创建和使用对象
public class Main {
    public static void main(String[] args) {
        // 创建学生对象
        Student student1 = new Student();
        
        // 设置属性
        student1.name = "张三";
        student1.age = 18;
        
        // 调用方法
        student1.showInfo();  // 输出:姓名:张三,年龄:18
        student1.study();     // 输出:张三正在学习
    }
}

构造方法

  • 用于初始化对象,与类同名,无返回类型
  • 创建对象时自动调用
  • 可以有多个构造方法(重载)
public class Student {
    String name;
    int age;
    
    // 无参构造方法
    public Student() {
        System.out.println("创建了一个学生对象");
    }
    
    // 有参构造方法
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

// 使用构造方法创建对象
Student student1 = new Student();
Student student2 = new Student("李四", 20);

继承

  • 使用extends关键字,子类继承父类的非私有属性和方法
  • Java只支持单继承(一个子类只能有一个直接父类)
  • 所有类都默认继承自Object类
// 父类
public class Person {
    String name;
    int age;
    
    public void eat() {
        System.out.println(name + "正在吃饭");
    }
}

// 子类
public class Student extends Person {
    String school;
    
    public void study() {
        System.out.println(name + "正在" + school + "学习");
    }
}

// 使用继承
public class Main {
    public static void main(String[] args) {
        Student student = new Student();
        student.name = "王五";  // 继承自Person的属性
        student.school = "清华大学";
        
        student.eat();    // 继承自Person的方法
        student.study();  // Student自己的方法
    }
}

多态

  • 方法重载(Overloading):同一个类中多个同名方法,参数列表不同

    public class Calculator {
        // 整数加法
        public int add(int a, int b) {
            return a + b;
        }
        
        // 浮点数加法
        public double add(double a, double b) {
            return a + b;
        }
        
        // 三个参数的加法
        public int add(int a, int b, int c) {
            return a + b + c;
        }
    }
    
  • 方法覆盖(Overriding):子类重写父类的方法,方法签名相同

    public class Animal {
        public void makeSound() {
            System.out.println("动物发出声音");
        }
    }
    
    public class Dog extends Animal {
        // 重写父类方法
        @Override
        public void makeSound() {
            System.out.println("汪汪汪");
        }
    }
    

抽象和接口

  • 抽象类:用abstract关键字修饰,可以有抽象方法和普通方法

    public abstract class Shape {
        // 抽象方法(没有方法体)
        public abstract double getArea();
        
        // 普通方法
        public void display() {
            System.out.println("这是一个形状");
        }
    }
    
    // 实现抽象类
    public class Circle extends Shape {
        private double radius;
        
        public Circle(double radius) {
            this.radius = radius;
        }
        
        // 必须实现抽象方法
        @Override
        public double getArea() {
            return Math.PI * radius * radius;
        }
    }
    
  • 接口:用interface关键字定义,只包含抽象方法(Java 8后也可以有默认方法)

    public interface Runnable {
        void run();  // 接口中的方法默认是public abstract的
    }
    
    // 实现接口
    public class Runner implements Runnable {
        @Override
        public void run() {
            System.out.println("开始跑步");
        }
    }
    

10. 异常处理

  • 异常是程序运行中出现的错误
  • Java异常体系结构:所有异常类都继承自Throwable

异常处理机制

  • try-catch:捕获并处理异常

    try {
        int result = 10 / 0;  // 这里会抛出ArithmeticException
        System.out.println("结果:" + result);
    } catch (ArithmeticException e) {
        System.out.println("发生算术异常:" + e.getMessage());
    }
    
  • try-catch-finally:无论是否发生异常,finally块都会执行

    try {
        // 可能抛出异常的代码
        FileReader file = new FileReader("file.txt");
        // 处理文件
    } catch (FileNotFoundException e) {
        System.out.println("文件不存在:" + e.getMessage());
    } finally {
        // 无论是否发生异常,都会执行的代码
        System.out.println("释放资源");
        // 关闭文件等操作
    }
    
  • try-with-resources:自动关闭资源(Java 7引入)

    try (FileReader fr = new FileReader("file.txt")) {
        // 使用fr读取文件
    } catch (IOException e) {
        e.printStackTrace();
    }
    

抛出异常

  • throw:手动抛出异常

    public void checkAge(int age) {
        if (age < 0) {
            throw new IllegalArgumentException("年龄不能为负数");
        }
    }
    
  • throws:声明方法可能抛出的异常

    public void readFile(String filename) throws FileNotFoundException {
        FileReader fr = new FileReader(filename);
        // 处理文件
    }
    

常见异常类型

  • RuntimeException(运行时异常):

    • NullPointerException:空指针异常
    • ArrayIndexOutOfBoundsException:数组越界异常
    • ArithmeticException:算术异常
    • ClassCastException:类型转换异常
  • 非RuntimeException(检查型异常):

    • IOException:输入输出异常
    • SQLException:数据库相关异常
    • FileNotFoundException:文件未找到异常

11. 集合框架

Java集合框架是处理和存储对象组的统一架构,主要包括:

List(列表)

有序集合,允许重复元素

  • ArrayList:基于动态数组实现,随机访问高效

    List<String> nameList = new ArrayList<>();
    nameList.add("张三");
    nameList.add("李四");
    System.out.println(nameList.get(0));  // 输出:张三
    
  • LinkedList:基于双向链表实现,插入和删除高效

    LinkedList<String> list = new LinkedList<>();
    list.add("A");
    list.addFirst("B");  // 在开头添加
    list.addLast("C");   // 在结尾添加
    

Set(集合)

不允许重复元素

  • HashSet:基于哈希表实现,无序

    Set<String> set = new HashSet<>();
    set.add("苹果");
    set.add("香蕉");
    set.add("苹果");  // 重复元素不会被添加
    System.out.println(set.size());  // 输出2
    
  • TreeSet:基于红黑树实现,有序

    TreeSet<Integer> numbers = new TreeSet<>();
    numbers.add(5);
    numbers.add(1);
    numbers.add(3);
    // 遍历(会按照1,3,5的顺序)
    for (Integer num : numbers) {
        System.out.println(num);
    }
    

Map(映射)

键值对集合,键不能重复

  • HashMap:基于哈希表实现,无序,高效

    Map<String, Integer> scores = new HashMap<>();
    scores.put("张三", 95);
    scores.put("李四", 88);
    System.out.println(scores.get("张三"));  // 输出:95
    
  • TreeMap:基于红黑树实现,按键排序

    TreeMap<String, String> countryCapitals = new TreeMap<>();
    countryCapitals.put("中国", "北京");
    countryCapitals.put("美国", "华盛顿");
    countryCapitals.put("日本", "东京");
    // 遍历(按照键的字母顺序)
    for (Map.Entry<String, String> entry : countryCapitals.entrySet()) {
        System.out.println(entry.getKey() + ": " + entry.getValue());
    }
    

Queue(队列)

  • PriorityQueue:优先队列,根据优先级进行排序
    Queue<Integer> queue = new PriorityQueue<>();
    queue.offer(3);
    queue.offer(1);
    queue.offer(2);
    System.out.println(queue.poll());  // 输出:1(最小值优先)
    

12. 多线程

创建线程的方式

  • 继承Thread类

    class MyThread extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 5; i++) {
                System.out.println("线程" + getName() + ": " + i);
            }
        }
    }
    
    // 使用
    MyThread thread1 = new MyThread();
    thread1.start();  // 启动线程
    
  • 实现Runnable接口

    class MyRunnable implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 5; i++) {
                System.out.println("线程: " + i);
            }
        }
    }
    
    // 使用
    Thread thread = new Thread(new MyRunnable());
    thread.start();
    
  • 使用匿名内部类

    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("线程运行中");
        }
    });
    thread.start();
    
  • 使用Lambda表达式(Java 8+)

    Thread thread = new Thread(() -> {
        System.out.println("使用Lambda创建的线程");
    });
    thread.start();
    

线程同步与安全

  • synchronized关键字:确保同一时间只有一个线程可以执行代码块

    public class Counter {
        private int count = 0;
        
        // 同步方法
        public synchronized void increment() {
            count++;
        }
        
        // 同步代码块
        public void incrementBlock() {
            synchronized(this) {
                count++;
            }
        }
    }
    
  • Lock接口:比synchronized更灵活的锁机制

    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class Counter {
        private int count = 0;
        private Lock lock = new ReentrantLock();
        
        public void increment() {
            lock.lock();  // 获取锁
            try {
                count++;
            } finally {
                lock.unlock();  // 释放锁
            }
        }
    }
    

线程状态和生命周期

  • 新建(New)
  • 可运行(Runnable)
  • 阻塞(Blocked)
  • 等待(Waiting)
  • 定时等待(Timed Waiting)
  • 终止(Terminated)

13. Java I/O

文件操作

  • File类:表示文件和目录
    File file = new File("test.txt");
    boolean exists = file.exists();  // 判断文件是否存在
    long size = file.length();       // 获取文件大小
    boolean created = file.createNewFile();  // 创建新文件
    
    File dir = new File("mydir");
    boolean dirCreated = dir.mkdir();  // 创建目录
    

输入输出流

  • 字节流:处理字节数据

    • InputStream:输入字节流
    • OutputStream:输出字节流
    // 读取文件
    try (FileInputStream fis = new FileInputStream("input.txt")) {
        int data;
        while ((data = fis.read()) != -1) {
            System.out.print((char) data);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    
    // 写入文件
    try (FileOutputStream fos = new FileOutputStream("output.txt")) {
        String text = "Hello, World!";
        fos.write(text.getBytes());
    } catch (IOException e) {
        e.printStackTrace();
    }
    
  • 字符流:处理字符数据

    • Reader:输入字符流
    • Writer:输出字符流
    // 读取文件
    try (FileReader fr = new FileReader("input.txt");
         BufferedReader br = new BufferedReader(fr)) {
        String line;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    
    // 写入文件
    try (FileWriter fw = new FileWriter("output.txt");
         BufferedWriter bw = new BufferedWriter(fw)) {
        bw.write("Hello, World!");
        bw.newLine();  // 添加换行
        bw.write("Java I/O!");
    } catch (IOException e) {
        e.printStackTrace();
    }
    

序列化

将对象转换为字节流,便于存储和传输

// 可序列化类
public class Person implements Serializable {
    private String name;
    private int age;
    
    // 构造方法、getter和setter方法
}

// 序列化对象到文件
try (ObjectOutputStream oos = new ObjectOutputStream(
        new FileOutputStream("person.dat"))) {
    Person person = new Person("张三", 25);
    oos.writeObject(person);
} catch (IOException e) {
    e.printStackTrace();
}

// 从文件反序列化对象
try (ObjectInputStream ois = new ObjectInputStream(
        new FileInputStream("person.dat"))) {
    Person person = (Person) ois.readObject();
    System.out.println(person.getName());
} catch (IOException | ClassNotFoundException e) {
    e.printStackTrace();
}

14. Java 8+新特性

Lambda表达式

匿名函数,简化代码

// 旧方式
Runnable r1 = new Runnable() {
    @Override
    public void run() {
        System.out.println("旧方式");
    }
};

// Lambda表达式
Runnable r2 = () -> System.out.println("Lambda方式");

// 带参数的Lambda
List<String> names = Arrays.asList("张三", "李四", "王五");
Collections.sort(names, (a, b) -> a.compareTo(b));

方法引用

进一步简化Lambda表达式

List<String> names = Arrays.asList("张三", "李四", "王五");

// Lambda表达式
names.forEach(x -> System.out.println(x));

// 方法引用
names.forEach(System.out::println);

Stream API

处理集合的强大工具

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);

// 使用Stream过滤、映射和收集
List<Integer> evenSquares = numbers.stream()
    .filter(n -> n % 2 == 0)       // 过滤偶数
    .map(n -> n * n)               // 映射为平方
    .collect(Collectors.toList());  // 收集到List

Optional类

避免空指针异常

// 传统方式
String name = null;
int length = 0;
if (name != null) {
    length = name.length();
}

// 使用Optional
Optional<String> optName = Optional.ofNullable(name);
int length = optName.map(String::length).orElse(0);

新的日期时间API

更好用的日期时间处理(java.time包)

// 获取当前日期
LocalDate today = LocalDate.now();
System.out.println(today);  // 如:2023-04-15

// 获取当前时间
LocalTime time = LocalTime.now();
System.out.println(time);   // 如:14:30:15.123

// 日期时间
LocalDateTime dateTime = LocalDateTime.now();
System.out.println(dateTime);  // 如:2023-04-15T14:30:15.123

// 日期计算
LocalDate nextWeek = today.plusWeeks(1);
LocalDate lastMonth = today.minusMonths(1);

// 格式化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
String formattedDate = today.format(formatter);  // 如:2023年04月15日

15. 小结

Java是一门功能强大、应用广泛的编程语言,从基础语法到高级特性都有丰富的内容。本笔记覆盖了Java的核心概念,对于初学者来说是一个不错的入门指南。继续学习和实践,你将能够利用Java开发各种类型的应用程序。

你可能感兴趣的:(java,笔记,开发语言)