Java语言特点
1.面向对象:Java 是一种面向对象的编程语言,支持封装、继承和多态等面向对象的特性,使得程序更易于理解、扩展和维护。
2.平台无关性:Java 程序通过 Java 虚拟机(JVM)在不同平台上运行,实现了“一次编写,到处运行”的特性,提高了程序的可移植性。
3.自动内存管理:Java 提供垃圾回收机制,自动管理内存分配和释放,减轻了开发人员对内存管理的负担,提高了程序的健壮性和稳定性。
4.丰富的类库:Java 提供了丰富的类库和 API,涵盖了各种功能模块,开发人员可以直接使用这些类库来加速开发,提高生产效率。
5.安全性:Java 具有强大的安全性特性,包括字节码验证、安全沙箱、安全管理器等,可以有效防止恶意代码的执行,保障系统的安全性。
6.多线程支持:Java 内置多线程支持,可以方便地创建和管理多个线程,实现并发编程,提高程序的性能和效率。
7.简单易学:Java 设计简洁,语法清晰明了,具有良好的可读性和可维护性,适合初学者入门,并且庞大的社区支持也使得学习资源丰富。
8.强大的开发工具:Java 生态系统中有丰富的开发工具,如 Eclipse、IntelliJ IDEA、NetBeans 等集成开发环境,提供丰富的功能和插件支持。
基础语法:
- 数据类型:Java 的数据类型用于声明变量时确定变量可以存储的数据类型。基本数据类型包括整型(int、long、short、byte)、浮点型(float、double)、布尔型(boolean)等。
自动类型转换
范围小的变量可以直接赋给范围大的变量
byte short int long float double
char
在表达式中,小范围类型的变量会自动转换成当前较大范围的类型再运算。
byte、short、char int long float double
- 变量:在 Java 中,变量需要先声明后使用。局部变量在方法、构造函数或块中声明,成员变量在类中声明但在方法外,静态变量用 static 关键字修饰。
- 运算符:Java 包含常见的算术运算符(+、-、*、/、%)、关系运算符(==、!=、>、<、>=、<=)和逻辑运算符(&&、||、!)等。
控制流结构:
-
顺序结构:
int a = 10; int b = 20; int c = a + b; System.out.println("a + b = " + c);
-
选择结构:
-
if-else 结构:根据条件判断执行不同的代码块。
//判断正负 int num = 10; if (num > 0) { System.out.println("数字是正数"); } else { System.out.println("数字是负数或零"); }
-
switch 结构:根据表达式的值匹配不同的 case 执行相应的代码块。
int day = 3; switch (day) { case 1: System.out.println("星期一"); break; case 2: System.out.println("星期二"); break; default: System.out.println("其他日期"); }
-
-
循环结构:
-
for 循环:用于循环执行固定次数的代码块。
for (int i = 1; i <= 5; i++) { System.out.println("i 的值为:" + i); }
-
while 循环:在条件为真时重复执行代码块。
int count = 0; while (count < 3) { System.out.println("count 的值为:" + count); count++; }
-
do-while 循环:先执行一次循环体,然后根据条件重复执行代码块。
int n = 1; do { System.out.println("n 的值为:" + n); n++; } while (n <= 3);
-
方法和函数:
- 方法(Method): 方法是面向对象编程中的一个重要概念,它是与特定类相关联的函数。方法定义了类的行为和操作,可以访问类的数据,并对其进行操作。方法通常被用来描述对象的行为或提供对象的功能。方法可以有返回值和参数,也可以没有。方法重载:在同一个类中,方法名相同但参数列表不同的多个方法,编译器根据调用时传递的参数数量或类型来区分。
public class Calculator { public int add(int a, int b) { return a + b; } public static void main(String[] args) { Calculator calculator = new Calculator(); int result = calculator.add(3, 5); System.out.println("The result is: " + result); } } //add 方法是 Calculator 类的一个方法,用于将两个整数相加并返回结果。
- 函数(Function): 函数是一段代码块,用于执行特定的任务或操作。函数通常被用来封装可重复使用的代码,以便在程序中多次调用。在一些编程语言中,如Python、JavaScript等,函数是一级对象,可以作为参数传递、赋值给变量等。
在函数式编程语言中,函数是主要的组织单元,它们通常不依赖于任何特定对象或类。
public class MathUtils { public static int multiply(int a, int b) { return a * b; } public static void main(String[] args) { int result = MathUtils.multiply(4, 6); System.out.println("The result is: " + result); } } //multiply 是一个静态函数,用于计算两个整数的乘积。通过调用 MathUtils.multiply(4, 6),我们可以得到数字 4 和 6 的乘积,并将结果打印出来。
异常处理:
- try-catch-finally:try 块中包含可能发生异常的代码,catch 块捕获并处理异常,finally 块无论是否发生异常都会执行。
public class ExceptionHandlingExample { public static void main(String[] args) { try { int result = divide(10, 0); System.out.println("Result: " + result); } catch (ArithmeticException e) { System.out.println("Error: Cannot divide by zero"); } } public static int divide(int dividend, int divisor) { if (divisor == 0) { throw new ArithmeticException("Cannot divide by zero"); } return dividend / divisor; } }
我们定义了一个
divide
方法,用于计算两个数相除的结果。在main
方法中,我们调用divide(10, 0)
来尝试做一个除法运算,但由于除数为零,会抛出一个ArithmeticException
异常。通过使用try-catch
块,我们捕获并处理这个异常,避免程序崩溃。
如果除数不为零,程序将正常执行,并输出结果。但如果除数为零,程序将打印出 "Error: Cannot divide by zero",而不会导致程序崩溃。这就是异常处理的基本用法,通过捕获和处理异常,我们可以使程序更加健壮和稳定。
- 自定义异常:通过继承 Exception 类或 RuntimeException 类来定义自己的异常类,可以根据业务逻辑定义不同类型的异常。
面向对象编程:
- 类与对象:类是对象的模板,对象是类的实例。类包括属性(字段)和方法,对象通过 new 关键字实例化。
例:在一个汽车制造厂中,Car 类可以表示汽车的属性和行为,而具体的一辆汽车实例则是该 Car 类的一个对象。
// 定义一个Car类 public class Car { private String brand; private String color; public void start() { System.out.println("The car is starting."); } } // 实例化一个Car对象 Car myCar = new Car(); myCar.brand = "Toyota"; myCar.color = "Red"; myCar.start();
- 抽象类和接口:抽象类包含抽象方法和非抽象方法,接口只包含抽象方法。类可以实现多个接口但只能继承一个类。
例:动物(Animal)可以是一个抽象类,定义了动物的基本属性和方法;飞行接口(Flyable)则定义了飞行的能力。
// 抽象类Animal public abstract class Animal { protected String name; public abstract void eat(); } // 接口Flyable public interface Flyable { void fly(); } // Dog类继承Animal类并实现Flyable接口 public class Dog extends Animal implements Flyable { public void eat() { System.out.println("Dog is eating."); } public void fly() { System.out.println("Dog can't fly."); } }
-
封装(Encapsulation): 封装是面向对象编程的基本特征之一,它将数据(属性)和行为(方法)封装在一个类中,并对外部隐藏对象的内部实现细节。通过封装,我们可以限制对对象的访问,只允许通过指定的接口来访问对象的属性和方法,这样可以提高安全性、灵活性和可维护性。
-
继承(Inheritance): 继承是面向对象编程的另一个重要特性,它允许一个类(子类)继承另一个类(父类)的属性和方法。通过继承,子类可以重用父类的代码,减少重复编码,提高代码的复用性。同时,子类可以在不改变父类结构的情况下扩展或修改其功能,实现代码的扩展性和灵活性。
-
多态(Polymorphism): 多态是面向对象编程的一个重要概念,它允许不同的对象对同一消息做出不同的响应。在Java中,多态性通常体现为方法重写(Override)和方法重载(Overload)。方法重写指子类可以重写父类的方法,实现不同的行为;方法重载指在同一个类中,可以拥有多个方法名相同但参数列表不同的方法。
- 继承和多态:子类可以继承父类的属性和方法,可以重写父类方法实现多态性,可以通过父类引用指向子类对象。
例:Bird 类继承自 Animal 类,重写了 eat 方法,实现了多态性。
// Bird类继承Animal类 public class Bird extends Animal { public void eat() { System.out.println("Bird is eating seeds."); } } // 多态性示例 Animal myBird = new Bird(); // 父类引用指向子类对象 myBird.eat(); // 调用子类重写的eat方法
集合框架:
-
List(列表): List 是一个有序的集合,允许重复元素。它继承自 Collection 接口,提供了按索引访问、添加、删除元素等功能。常见的 List 实现类包括 ArrayList、LinkedList 和 Vector。
-
Set(集合): Set 是一个不允许重复元素的集合,确保集合中的每个元素都是唯一的。它继承自 Collection 接口,通常用于存储不重复的对象。常见的 Set 实现类包括 HashSet、TreeSet 和 LinkedHashSet。
-
Map(映射): Map 是一种键值对映射的集合,每个键对应一个值。它不继承自 Collection 接口,而是独立存在。常见的 Map 实现类包括 HashMap、TreeMap 和 LinkedHashMap,其中 HashMap 是最常用的实现类。
-
Queue(队列): Queue 是一种先进先出(FIFO)的集合,通常用于处理元素的顺序。它继承自 Collection 接口,并提供了插入、删除和检查元素的操作。常见的 Queue 实现类包括 LinkedList、PriorityQueue 等。
-
Stack(栈): Stack 是一种后进先出(LIFO)的集合,通常用于实现栈数据结构。它继承自 Vector 类,提供了 push、pop、peek 等操作来管理栈中的元素。
- 遍历集合的不同方式:可以使用 for-each 循环遍历集合,也可以使用迭代器(Iterator)来遍历并操作集合中的元素。
输入输出(I/O):
1.文件读写:
通过 FileInputStream 和 FileOutputStream 类进行文件的读写操作,BufferedReader 和 BufferedWriter 可以提供缓冲功能提高读写效率。
import java.io.*;
public class FileReadWriteExample {
public static void main(String[] args) {
// 文件写入示例
try (FileOutputStream fos = new FileOutputStream("output.txt");
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos))) {
writer.write("Hello, World!");
System.out.println("文件写入成功!");
} catch (IOException e) {
System.out.println("文件写入失败:" + e.getMessage());
}
// 文件读取示例
try (FileInputStream fis = new FileInputStream("output.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(fis)) {
String line = reader.readLine();
System.out.println("从文件中读取的内容:" + line);
} catch (IOException e) {
System.out.println("文件读取失败:" + e.getMessage());
}
}
}
在上述代码中,使用 FileOutputStream 和 BufferedWriter 将字符串写入到文件 "output.txt" 中,然后使用 FileInputStream 和 BufferedReader 从文件中读取内容并输出到控制台。
2. 序列化和反序列化:
通过实现 Serializable 接口,对象可以以字节序列的形式在网络上传输或保存到磁盘,ObjectInputStream 和 ObjectOutputStream 用于对象的读写。
import java.io.*;
class Person implements Serializable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
}
public class SerializationExample {
public static void main(String[] args) {
// 序列化对象
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"))) {
Person person = new Person("Alice", 30);
oos.writeObject(person);
System.out.println("对象已被序列化");
} catch (IOException e) {
System.out.println("序列化失败:" + e.getMessage());
}
// 反序列化对象
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"))) {
Person person = (Person) ois.readObject();
System.out.println("反序列化的对象:" + person);
} catch (IOException | ClassNotFoundException e) {
System.out.println("反序列化失败:" + e.getMessage());
}
}
}
该代码定义了一个 Person 类并实现了 Serializable 接口,然后通过 ObjectOutputStream 将 Person 对象序列化到文件 "person.ser" 中,之后通过 ObjectInputStream 从文件中反序列化出对象并输出到控制台。
并发编程:
1.线程创建和管理:
通过 Thread 类或实现 Runnable 接口来创建线程,可以通过 start() 方法启动线程。
使用 Thread 类创建线程:
public class MyThread extends Thread {
public void run() {
System.out.println("MyThread is running");
}
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
}
}
使用 Runnable 接口实现线程:
public class MyRunnable implements Runnable {
public void run() {
System.out.println("MyRunnable is running");
}
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
thread.start();
}
}
2.同步和锁机制:
通过实现 Serializable 接口,对象可以以字节序列的形式在网络上传输或保存到磁盘,ObjectInputStream 和 ObjectOutputStream 用于对象的读写。
使用 synchronized 关键字同步方法:
public class SynchronizedExample {
private int count = 0;
public synchronized void increment() {
count++;
}
public static void main(String[] args) {
SynchronizedExample example = new SynchronizedExample();
for (int i = 0; i < 10; i++) {
new Thread(() -> {
example.increment();
}).start();
}
System.out.println("Count: " + example.count);
}
}
使用 Lock 接口提供更灵活的锁机制:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockExample {
private int count = 0;
private Lock lock = new ReentrantLock();
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
LockExample example = new LockExample();
for (int i = 0; i < 10; i++) {
new Thread(() -> {
example.increment();
}).start();
}
System.out.println("Count: " + example.count);
}
}
设计模式:
1.创建型模式:
-
工厂模式:工厂模式是一种设计模式,用于封装对象的创建逻辑,使得在需要创建对象时只需关注工厂类即可,而不需要直接实例化对象。这样可以降低代码耦合度,提高代码的可维护性和灵活性。
-
单例模式:单例模式是一种设计模式,确保一个类只有一个实例,并提供一个全局访问点。这样可以节约系统资源,避免多个实例之间的数据不一致性,常用于需要全局唯一实例的场景。
2.结构型模式:
-
适配器模式:适配器模式用于解决不同接口之间不兼容的问题,通过适配器将一个接口转换成客户端所期待的另一个接口,使得原本由于接口不匹配而无法在一起工作的类能够协同工作。
-
装饰者模式:装饰者模式是一种设计模式,用于动态地给对象添加额外的功能,而不需要改变其接口。通过装饰者模式,可以在不改变原始对象结构的情况下,动态地添加功能。
3.行为型模式:
-
观察者模式:观察者模式定义了一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都会得到通知并自动更新。这种模式用于对象之间的订阅-发布关系。
-
策略模式:策略模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。客户端可以根据需求选择不同的算法,从而使得算法可以独立于客户端而变化。
JVM:
- 内存模型:堆用于存储对象实例,栈用于存储基本数据类型和方法调用信息,方法区用于存储类信息、常量池等。
- 垃圾回收算法:标记-清除算法、标记-整理算法、复制算法等,用于释放不再使用的对象占用的内存空间。
Java核心库:
java.lang、java.util、java.io 等包提供了丰富的核心功能,如字符串处理、日期时间操作、正则表达式、集合操作等。
网络编程:
- Socket 编程:通过 Socket 和 ServerSocket 类进行网络通信,客户端和服务器端通过套接字建立连接。
- URLConnection 和 HttpClient:用于发送 HTTP 请求和接收 HTTP 响应,HttpClient 是 Apache 提供的 HTTP 客户端库。
- NIO 和异步非阻塞 I/O:通过 java.nio 包提供的新 I/O API 实现高性能的 I/O 操作,支持通道、缓冲区等概念。