数据类型
Java提供了八种基本数据类型(Primitive Data Types),分为四类:整数类型、浮点类型、字符类型和布尔类型。
基本数据类型:
整数类型:byte
,short
,int
,long
浮点类型:float
, double
字符类型:char
布尔类型:boolean
- 案例:定义一个整型变量并赋值。
int age = 25;
- 引用数据类型:类(Class)、接口(Interface)、数组(Array)、枚举(Enum)以及注解(Annotation)
- 案例:创建一个字符串对象(String属于引用数据类型中的类!!!)。
String name = new String("张三");
- 案例:创建一个字符串对象(String属于引用数据类型中的类!!!)。
循环结构
- for循环:用于遍历集合或执行固定次数的操作。
- 案例:打印0到9的数字。
for (int i = 0; i < 10; i++) { System.out.println(i); }
- 案例:打印0到9的数字。
- while循环:当条件为真时重复执行代码块。
- 案例:使用while循环读取文件直到结束。
while ((line = bufferedReader.readLine()) != null) { System.out.println(line); }
- 案例:使用while循环读取文件直到结束。
数组
- 一维数组:存储相同类型的元素集合。
- 案例:初始化并操作数组。
int[] numbers = {1, 2, 3, 4, 5}; System.out.println(numbers[0]); // 输出1
- 案例:初始化并操作数组。
- 多维数组:可以看作是“数组的数组”。
- 案例:二维数组的初始化与访问。
int[][] matrix = {{1, 2}, {3, 4}}; System.out.println(matrix[0][1]); // 输出2
- 案例:二维数组的初始化与访问。
字符和字符串
- 字符:使用单引号表示,如
'A'
。- 案例:声明变量
char letter = "A"; char chineseChar = "张";
- 案例:声明变量
- 字符串:使用双引号表示,如
"Hello World"
。- 案例:字符串连接。
String firstName = "张"; String lastName= "三"; System.out.println(firstName + " " + lastName); // 输出张 三
- 案例:字符串连接。
面向对象思想
封装、继承、多态和抽象是面向对象编程的四大特性。
面向对象编程(OOP)是一种编程范式,它通过“对象”来组织代码,这些对象是类的实例。OOP的四大特性——封装、继承、多态和抽象——是其核心概念,帮助开发者构建模块化、可维护和可扩展的软件系统。
1. 封装(Encapsulation)
封装指的是将数据(属性)和操作数据的方法捆绑在一起,并限制对数据的直接访问,从而保护数据免受外部干扰和误用。通过使用访问修饰符(如private
, protected
, public
),可以控制类成员的可见性。
-
好处:
- 提高安全性:隐藏内部状态,仅允许通过安全的方式访问。
- 增强灵活性:可以在不影响其他部分的情况下修改或扩展内部实现。
-
案例:
public class Person { private String name; private int age; // Getter for name public String getName() { return name; } // Setter for name public void setName(String name) { this.name = name; } // Getter for age public int getAge() { return age; } // Setter for age with validation public void setAge(int age) { if (age > 0 && age < 120) { this.age = age; } else { System.out.println("Invalid age"); } } }
2. 继承(Inheritance)
继承允许一个类从另一个类中继承属性和方法,从而促进代码重用并建立类之间的关系。子类(派生类)可以继承父类(基类)的所有公开和受保护的成员,并且还可以添加自己的新功能或覆盖现有功能。
-
好处:
- 代码重用:避免重复编写相同的代码。
- 层次结构:有助于组织类之间的层次关系。
-
案例:
class Animal { void eat() { System.out.println("This animal eats food."); } } class Dog extends Animal { void bark() { System.out.println("The dog barks."); } } public class Main { public static void main(String[] args) { Dog dog = new Dog(); dog.eat(); // Inherited method dog.bark(); // Own method } }
3. 多态(Polymorphism)
多态允许不同类的对象通过相同的接口调用不同的行为。这意味着同一个方法名可以在不同的类中有不同的实现。多态可以通过方法重载(编译时多态)和方法重写(运行时多态)来实现。
-
好处:
- 灵活性:可以根据对象的实际类型动态选择合适的方法。
- 扩展性:容易添加新的子类而不影响现有代码。
-
案例:
class Animal { void sound() { System.out.println("Some generic animal sound"); } } class Cat extends Animal { @Override void sound() { System.out.println("Meow"); } } class Dog extends Animal { @Override void sound() { System.out.println("Bark"); } } public class Main { public static void main(String[] args) { Animal myCat = new Cat(); Animal myDog = new Dog(); myCat.sound(); // Outputs: Meow myDog.sound(); // Outputs: Bark } }
4. 抽象(Abstraction)
抽象是指隐藏复杂的实现细节,只向外界暴露简单的接口。抽象类和接口是实现抽象的主要手段。抽象类不能被实例化,只能被继承;而接口则定义了一组方法,但不提供具体实现,由实现类提供具体的实现。
-
好处:
- 简化复杂性:用户只需知道如何使用接口,无需了解内部实现。
- 强制规范:确保所有实现类都遵循相同的接口标准。
-
案例:
abstract class Shape { abstract void draw(); } class Circle extends Shape { @Override void draw() { System.out.println("Drawing a circle"); } } class Rectangle extends Shape { @Override void draw() { System.out.println("Drawing a rectangle"); } } public class Main { public static void main(String[] args) { Shape circle = new Circle(); Shape rectangle = new Rectangle(); circle.draw(); // Outputs: Drawing a circle rectangle.draw(); // Outputs: Drawing a rectangle } }
此外,Java还支持使用interface
关键字定义接口,接口中的所有方法默认都是抽象的。
- 接口示例:
interface Drawable { void draw(); } class Circle implements Drawable { @Override public void draw() { System.out.println("Drawing a circle using interface"); } } public class Main { public static void main(String[] args) { Drawable drawable = new Circle(); drawable.draw(); // Outputs: Drawing a circle using interface } }
异常
检查性异常、运行时异常和错误。
在Java中,异常处理是编程的重要部分,它帮助程序在遇到问题时能够优雅地处理错误而不是直接崩溃。Java中的异常分为三大类:检查性异常(Checked Exceptions)、运行时异常(Unchecked Exceptions)和错误(Errors)。每种类型的异常有不同的用途和处理方式。
1. 检查性异常(Checked Exceptions)
检查性异常是指那些在编译时被强制检查的异常。它们通常是外部因素导致的问题,如文件不存在、网络连接失败等。如果一个方法可能抛出检查性异常,必须在方法签名中声明该异常,或者在方法内部使用try-catch
块捕获并处理该异常。
-
特点:
- 必须显式处理(通过
try-catch
或throws
关键字)。 - 表示可以恢复的异常情况。
- 必须显式处理(通过
-
常见例子:
IOException
:与输入输出操作相关的异常。SQLException
:与数据库访问相关的异常。
-
案例:
import java.io.*; public class FileReaderExample { public static void main(String[] args) { try { FileReader file = new FileReader("file.txt"); BufferedReader fileInput = new BufferedReader(file); String line; while ((line = fileInput.readLine()) != null) { System.out.println(line); } fileInput.close(); } catch (IOException e) { System.out.println("An error occurred: " + e.getMessage()); } } }
2. 运行时异常(Unchecked Exceptions)
运行时异常是在程序执行过程中发生的异常,这些异常不需要在编译时声明或捕获。它们通常是由程序逻辑错误引起的,如数组越界、空指针引用等。虽然可以捕获这些异常,但最好通过改进代码来避免这些问题。
-
特点:
- 不需要显式声明或捕获。
- 表示编程错误或不可预见的情况。
-
常见例子:
NullPointerException
:当试图访问一个null
对象的方法或属性时抛出。ArrayIndexOutOfBoundsException
:当数组下标超出范围时抛出。
-
案例:
public class NullPointerExample { public static void main(String[] args) { String str = null; try { System.out.println(str.length()); } catch (NullPointerException e) { System.out.println("Null pointer exception caught: " + e.getMessage()); } } }
3. 错误(Errors)
错误是严重的系统级问题,通常表示程序无法继续正常运行。与异常不同,错误通常是不可恢复的,并且不应该被程序捕获或处理。常见的错误包括内存溢出、栈溢出等。
-
特点:
- 通常不可恢复。
- 程序通常不应尝试捕获或处理这些错误。
-
常见例子:
OutOfMemoryError
:当JVM耗尽内存时抛出。StackOverflowError
:当递归调用过深导致栈空间不足时抛出。
-
案例:
public class StackOverflowExample { public static void main(String[] args) { recursiveMethod(); } public static void recursiveMethod() { recursiveMethod(); // This will cause a StackOverflowError eventually } }
总结
- 检查性异常:需要显式处理,通常用于表示可恢复的外部问题。
- 运行时异常:不需要显式处理,通常用于表示编程错误或不可预见的情况。
- 错误:通常不可恢复,表示严重的系统级问题,不建议在程序中捕获或处理。
Socket
用于网络通信,允许程序通过网络发送和接收数据。
在Java中,Socket
类用于实现客户端和服务器之间的网络通信。通过Socket
,你可以建立连接、发送数据和接收数据。下面详细描述如何使用Socket
进行简单的客户端-服务器通信,并提供一个完整的示例。
客户端Socket连接
客户端需要创建一个Socket
对象来连接到服务器,并通过该套接字的输入输出流与服务器进行通信。以下是一个简单的客户端示例,展示如何连接到服务器并发送消息。
1. 创建客户端Socket连接
import java.io.*;
import java.net.Socket;
public class SimpleClient {
public static void main(String[] args) {
String hostname = "localhost"; // 服务器地址
int port = 8080; // 服务器端口
try (Socket socket = new Socket(hostname, port)) {
// 获取输出流,用于向服务器发送数据
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
// 向服务器发送消息
out.println("Hello Server");
// 获取输入流,用于从服务器接收数据
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String response = in.readLine();
// 打印服务器响应
System.out.println("Server response: " + response);
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务器Socket监听
为了使上述客户端代码正常工作,你需要一个服务器程序来监听指定端口并处理来自客户端的请求。以下是服务器端的实现示例:
2. 创建服务器Socket监听
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class SimpleServer {
public static void main(String[] args) {
int port = 8080; // 监听端口
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println("Server is listening on port " + port);
while (true) {
// 等待客户端连接
Socket socket = serverSocket.accept();
System.out.println("New client connected");
// 获取输入流,用于读取客户端发送的数据
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String messageFromClient = in.readLine();
System.out.println("Message from client: " + messageFromClient);
// 获取输出流,用于向客户端发送数据
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.println("Hello Client, I received your message: " + messageFromClient);
// 关闭当前客户端连接
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行步骤
-
启动服务器:首先运行
SimpleServer
类,它会开始监听指定端口(如8080)上的连接。java SimpleServer
-
启动客户端:然后运行
SimpleClient
类,它会尝试连接到本地服务器,并发送一条消息。java SimpleClient
-
查看结果:
- 在客户端控制台,你会看到类似以下输出:
Server response: Hello Client, I received your message: Hello Server
- 在服务器控制台,你会看到类似以下输出:
Server is listening on port 8080 New client connected Message from client: Hello Server
- 在客户端控制台,你会看到类似以下输出:
解释
-
客户端部分:
Socket socket = new Socket(hostname, port);
:创建一个连接到指定主机和端口的Socket对象。PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
:获取Socket的输出流,用于发送数据到服务器。out.println("Hello Server");
:发送消息到服务器。BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
:获取Socket的输入流,用于读取服务器的响应。String response = in.readLine();
:读取服务器的响应。
-
服务器部分:
ServerSocket serverSocket = new ServerSocket(port);
:创建一个监听指定端口的ServerSocket对象。Socket socket = serverSocket.accept();
:等待并接受客户端连接。BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
:获取客户端的输入流,用于读取客户端发送的数据。PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
:获取客户端的输出流,用于发送数据到客户端。socket.close();
:关闭当前客户端连接。
通过这种方式,你可以实现基本的客户端-服务器通信,进一步可以根据需求扩展功能,例如处理多个客户端连接、发送复杂数据结构等。
JDBC
用于数据库连接和操作的标准API。
Java Database Connectivity (JDBC) 是 Java 应用程序与数据库之间进行交互的标准 API。通过 JDBC,你可以执行 SQL 查询、更新数据、调用存储过程等操作。
1. 设置环境
在开始之前,确保你已经完成以下准备工作:
- 安装 MySQL 数据库:如果你还没有安装 MySQL 数据库,请先安装并启动它。
- 添加 JDBC 驱动依赖:你需要下载并添加 MySQL JDBC 驱动(
mysql-connector-java
)到你的项目中。可以通过 Maven 或直接下载 JAR 文件。
使用 Maven 添加依赖
如果你使用的是 Maven 项目,在 pom.xml
文件中添加以下依赖:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version> <!-- 确保版本号是最新的 -->
</dependency>
2. 编写代码连接数据库并执行查询
以下是详细的步骤和代码示例,展示如何使用 JDBC 连接到 MySQL 数据库并执行查询。
2.1 导入必要的包
首先,导入需要的包:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
2.2 加载驱动并获取连接
使用 DriverManager
类来加载 JDBC 驱动并获取数据库连接。
public class JdbcExample {
public static void main(String[] args) {
// 数据库连接参数
String jdbcUrl = "jdbc:mysql://localhost:3306/mydb"; // 数据库URL
String username = "user"; // 数据库用户名
String password = "password"; // 数据库密码
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
// 加载MySQL JDBC驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 获取数据库连接
conn = DriverManager.getConnection(jdbcUrl, username, password);
System.out.println("Connected to the database!");
// 创建Statement对象
stmt = conn.createStatement();
// 执行查询
String sql = "SELECT * FROM employees";
rs = stmt.executeQuery(sql);
// 处理结果集
while (rs.next()) {
// 获取列值
int id = rs.getInt("id");
String name = rs.getString("name");
String position = rs.getString("position");
double salary = rs.getDouble("salary");
// 输出结果
System.out.printf("ID: %d, Name: %s, Position: %s, Salary: %.2f%n", id, name, position, salary);
}
} catch (ClassNotFoundException e) {
System.err.println("MySQL JDBC Driver not found.");
e.printStackTrace();
} catch (SQLException e) {
System.err.println("SQL Exception occurred.");
e.printStackTrace();
} finally {
// 关闭资源
try {
if (rs != null) rs.close();
if (stmt != null) stmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
这个示例展示了如何使用 JDBC 连接到 MySQL 数据库并执行一个简单的查询。你可以根据实际需求修改 SQL 语句和处理逻辑,以适应更复杂的应用场景。