Java学习第六部分——API部分(续)
目录
一、日期时间处理
1. Date类
2. Calendar类
3. Java 8新日期时间API
二、异常处理
1. Exception类
2. try-catch-finally块
三、线程和并发
1. Thread类
2. 同步机制
3. 并发工具类
四.日期时间处理——idea项目应用
五.异常处理——idea项目应用
六.线程与并发——idea项目应用
ps:在Java编程中,日期时间处理、异常处理和线程并发是三个极为关键的领域。它们不仅关乎程序的健壮性、效率,还直接影响到程序的可维护性和用户体验。
一、日期时间处理
日期时间处理是编程中常见的需求,无论是记录日志、处理用户输入的日期,还是计算时间间隔,都需要灵活且强大的日期时间API支持。
1. Date类
`Date`类是Java早期提供的日期时间类,它可以表示日期和时间。通过`new Date()`可以直接获取当前的日期和时间。此外,`Date`类还提供了一些方法用于日期时间的转换,但这些方法相对较为繁琐。
import java.util.Date;
public class DateExample {
public static void main(String[] args) {
// 获取当前日期和时间
Date currentDate = new Date();
System.out.println("当前日期和时间:" + currentDate);
// 转换日期时间格式(需要借助SimpleDateFormat类)
// Java 8之前日期时间处理较为繁琐
// Java 8引入了新的日期时间API,推荐使用
}
}
2. Calendar类
`Calendar`类用于日期和时间的计算,提供了更灵活的日期操作功能。例如,你可以通过`Calendar`类获取当前日期的年份、月份和日期,并且可以方便地进行日期的加减运算。
import java.util.Calendar;
public class CalendarExample {
public static void main(String[] args) {
// 获取默认的Calendar实例
Calendar calendar = Calendar.getInstance();
System.out.println("当前年份:" + calendar.get(Calendar.YEAR));
System.out.println("当前月份:" + (calendar.get(Calendar.MONTH) + 1)); // 月份从0开始
System.out.println("当前日期:" + calendar.get(Calendar.DAY_OF_MONTH));
// 日期时间计算示例:将日期加10天
calendar.add(Calendar.DAY_OF_MONTH, 10);
System.out.println("加10天后的日期:" + calendar.get(Calendar.YEAR) + "-" + (calendar.get(Calendar.MONTH) + 1) + "-" + calendar.get(Calendar.DAY_OF_MONTH));
}
}
3. Java 8新日期时间API
Java 8引入了新的日期时间API,包括`LocalDate`、`LocalTime`和`LocalDateTime`,这些类提供了更强大的日期时间处理功能。新API的设计更加合理,避免了`Date`类和`Calendar`类的一些问题,如线程安全问题和复杂的API设计。
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class NewDateTimeExample {
public static void main(String[] args) {
// 获取当前日期、时间和日期时间
LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.now();
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("当前日期:" + localDate);
System.out.println("当前时间:" + localTime);
System.out.println("当前日期时间:" + localDateTime);
// 日期时间格式化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedDateTime = localDateTime.format(formatter);
System.out.println("格式化后的日期时间:" + formattedDateTime);
// 日期时间计算示例:将日期加10天
LocalDate newDate = localDate.plusDays(10);
System.out.println("加10天后的日期:" + newDate);
}
}
二、异常处理
异常处理是Java编程中不可或缺的一部分。它可以帮助我们处理程序运行时可能出现的错误情况,确保程序的稳定性和可靠性。
1. Exception类
`Exception`类是所有异常的父类,它表示程序运行时可能出现的异常情况。`Exception`类提供了一些常用方法,如`getMessage()`用于获取异常信息,`printStackTrace()`用于打印异常堆栈信息。
public class ExceptionExample {
public static void main(String[] args) {
try {
// 模拟可能抛出异常的代码
int result = 10 / 0; // 除以0,抛出ArithmeticException
} catch (Exception e) {
// 捕获并处理异常
System.out.println("捕获到异常:" + e.getMessage());
e.printStackTrace(); // 打印异常堆栈信息
}
}
}
2. try-catch-finally块
`try-catch-finally`块是Java中用于捕获和处理异常的结构。`try`块包含可能抛出异常的代码,`catch`块用于捕获和处理异常,`finally`块用于执行清理操作,无论是否捕获到异常,`finally`块中的代码都会被执行。
public class TryCatchFinallyExample {
public static void main(String[] args) {
try {
// 模拟可能抛出异常的代码
int result = 10 / 0; // 除以0,抛出ArithmeticException
} catch (ArithmeticException e) {
// 捕获并处理特定类型的异常
System.out.println("捕获到ArithmeticException:" + e.getMessage());
} catch (Exception e) {
// 捕获其他类型的异常
System.out.println("捕获到其他异常:" + e.getMessage());
} finally {
// 无论是否捕获到异常,都会执行finally块中的代码
System.out.println("finally块中的代码被执行");
}
}
}
三、线程和并发
在多核处理器时代,线程和并发是提高程序性能和响应能力的重要手段。Java提供了丰富的线程和并发工具,帮助我们更好地利用多核处理器的性能。
1. Thread类
`Thread`类用于创建和管理线程。你可以通过实现`Runnable`接口或继承`Thread`类来创建线程。
// 实现Runnable接口创建线程
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("通过实现Runnable接口创建的线程正在运行");
}
}
// 继承Thread类创建线程
class MyThread extends Thread {
@Override
public void run() {
System.out.println("通过继承Thread类创建的线程正在运行");
}
}
public class ThreadExample {
public static void main(String[] args) {
// 创建并启动线程
Thread thread1 = new Thread(new MyRunnable());
thread1.start();
Thread thread2 = new MyThread();
thread2.start();
}
}
2. 同步机制
在多线程环境中,同步机制是确保线程安全的关键。`synchronized`关键字是Java中最常用的同步机制之一,它可以用于控制线程同步,避免线程安全问题。
class Counter {
private int count = 0;
// 同步方法
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
public class SynchronizedExample {
public static void main(String[] args) {
final Counter counter = new Counter();
// 创建多个线程对Counter对象进行操作
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});
thread1.start();
thread2.start();
try {
thread1.join(); // 等待线程1执行完毕
thread2.join(); // 等待线程2执行完毕
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("最终计数:" + counter.getCount());
}
}
3. 并发工具类
Java提供了丰富的并发工具类,如`ExecutorService`(线程池)、`Future`(异步任务)、`CountDownLatch`(倒计时锁存器)等,用于更高级的并发控制。
ExecutorService(线程池)
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorServiceExample {
public static void main(String[] args) {
// 创建固定大小的线程池
ExecutorService executorService = Executors.newFixedThreadPool(2);
// 提交任务到线程池
executorService.submit(() -> {
System.out.println("任务1正在执行");
});
executorService.submit(() -> {
System.out.println("任务2正在执行");
});
// 关闭线程池
executorService.shutdown();
}
}
Future(异步任务)
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class FutureExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建FutureTask对象
FutureTask<Integer> futureTask = new FutureTask<>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
// 模拟耗时任务
Thread.sleep(2000);
return 100;
}
});
// 启动任务
new Thread(futureTask).start();
// 获取任务结果
Integer result = futureTask.get();
System.out.println("异步任务结果:" + result);
}
}
CountDownLatch(倒计时锁存器)
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public static void main(String[] args) throws InterruptedException {
final int threadCount = 3;
CountDownLatch countDownLatch = new CountDownLatch(threadCount);
for (int i = 0; i < threadCount; i++) {
new Thread(() -> {
System.out.println("线程" + Thread.currentThread().getName() + "开始执行");
try {
// 模拟线程执行任务
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程" + Thread.currentThread().getName() + "执行完毕");
countDownLatch.countDown(); // 线程执行完毕,计数减1
}).start();
}
// 主线程等待所有线程执行完毕
countDownLatch.await();
System.out.println("所有线程执行完毕");
}
}
四.日期时间处理——idea项目应用
-
打开IDEA,创建一个新的Java项目。
-
在项目中创建
com.example
包。 -
在
com.example
包下创建DateTimeTest
和TestZone
类。 -
将上述代码分别复制到对应的类中。
package com.example;import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime;public class DateTimeTest {public static void main(String[] args) {// 获取当前日期、时间和日期时间LocalDate localDate = LocalDate.now();LocalTime localTime = LocalTime.now();LocalDateTime localDateTime = LocalDateTime.now();System.out.println("当前日期:" + localDate);System.out.println("当前时间:" + localTime);System.out.println("当前日期时间:" + localDateTime);// 创建指定日期时间LocalDate localDate1 = LocalDate.of(2021, 12, 12);LocalDateTime localDateTime1 = LocalDateTime.of(2021, 12, 5, 23, 22, 45);System.out.println("指定日期:" + localDate1);System.out.println("指定日期时间:" + localDateTime1);} }
package com.example;import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.Set;public class TestZone {public static void main(String[] args) {// 获取所有可用的时区IDSet<String> availableZoneIds = ZoneId.getAvailableZoneIds();for (String availableZoneId : availableZoneIds) {System.out.println(availableZoneId);}// 获取当前时区的日期时间ZonedDateTime t1 = ZonedDateTime.now();System.out.println("当前时区的日期时间:" + t1);// 获取指定时区的日期时间ZonedDateTime t2 = ZonedDateTime.now(ZoneId.of("America/New_York"));System.out.println("指定时区的日期时间:" + t2);} }
-
运行
DateTimeTest
和TestZone
类,查看输出结果。 -
解释如下
-
LocalDate、LocalTime、LocalDateTime:分别用于表示日期、时间和日期时间。
-
ZoneId、ZonedDateTime:用于处理时区相关的日期时间。
-
DateTimeFormatter:用于格式化日期时间。
五.异常处理——idea项目应用
-
打开IDEA,创建一个新的Java项目。
-
在项目中创建
com.example
包。 -
在
com.example
包下创建ExceptionTest
和CustomException
类。 -
将上述代码分别复制到对应的类中。
package com.example;public class ExceptionTest {public static void main(String[] args) {// 示例1:捕获和处理ArithmeticExceptiontry {int result = 10 / 0; // 除以0,抛出ArithmeticException} catch (ArithmeticException e) {System.out.println("捕获到ArithmeticException:" + e.getMessage());e.printStackTrace(); // 打印异常堆栈信息}// 示例2:try-catch-finally块try {int[] array = {1, 2, 3};System.out.println(array[3]); // 访问数组越界,抛出ArrayIndexOutOfBoundsException} catch (ArrayIndexOutOfBoundsException e) {System.out.println("捕获到ArrayIndexOutOfBoundsException:" + e.getMessage());} finally {System.out.println("finally块中的代码被执行");}// 示例3:抛出自定义异常try {throw new CustomException("这是一个自定义异常");} catch (CustomException e) {System.out.println("捕获到自定义异常:" + e.getMessage());}} }
package com.example;// 自定义异常类 public class CustomException extends Exception {public CustomException(String message) {super(message);} }
-
运行
ExceptionTest
类,查看输出结果。 -
解释如下
-
ArithmeticException:演示了如何捕获和处理除以0的异常。
-
try-catch-finally块:演示了如何使用
try-catch-finally
块捕获和处理数组越界异常,并展示了finally
块的执行。 -
自定义异常:演示了如何定义和抛出自定义异常。
六.线程与并发——idea项目应用
-
打开IDEA,创建一个新的Java项目。
-
在项目中创建
com.example
包。 -
在
com.example
包下创建ThreadTest
、SynchronizedTest
、ExecutorServiceTest
、FutureTest
和CountDownLatchTest
类。 -
将上述代码分别复制到对应的类中。
package com.example;// 实现Runnable接口创建线程 class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println("通过实现Runnable接口创建的线程正在运行:" + Thread.currentThread().getName());} }// 继承Thread类创建线程 class MyThread extends Thread {@Overridepublic void run() {System.out.println("通过继承Thread类创建的线程正在运行:" + Thread.currentThread().getName());} }public class ThreadTest {public static void main(String[] args) {// 创建并启动线程Thread thread1 = new Thread(new MyRunnable());thread1.start();Thread thread2 = new MyThread();thread2.start();} }
package com.example;class Counter {private int count = 0;// 同步方法public synchronized void increment() {count++;}public synchronized int getCount() {return count;} }public class SynchronizedTest {public static void main(String[] args) {final Counter counter = new Counter();// 创建多个线程对Counter对象进行操作Thread thread1 = new Thread(() -> {for (int i = 0; i < 1000; i++) {counter.increment();}});Thread thread2 = new Thread(() -> {for (int i = 0; i < 1000; i++) {counter.increment();}});thread1.start();thread2.start();try {thread1.join(); // 等待线程1执行完毕thread2.join(); // 等待线程2执行完毕} catch (InterruptedException e) {e.printStackTrace();}System.out.println("最终计数:" + counter.getCount());} }
package com.example;import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;public class ExecutorServiceTest {public static void main(String[] args) {// 创建固定大小的线程池ExecutorService executorService = Executors.newFixedThreadPool(2);// 提交任务到线程池executorService.submit(() -> {System.out.println("任务1正在执行:" + Thread.currentThread().getName());});executorService.submit(() -> {System.out.println("任务2正在执行:" + Thread.currentThread().getName());});// 关闭线程池executorService.shutdown();} }
package com.example;import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask;public class FutureTest {public static void main(String[] args) throws ExecutionException, InterruptedException {// 创建FutureTask对象FutureTask<Integer> futureTask = new FutureTask<>(new Callable<Integer>() {@Overridepublic Integer call() throws Exception {// 模拟耗时任务Thread.sleep(2000);return 100;}});// 启动任务new Thread(futureTask).start();// 获取任务结果Integer result = futureTask.get();System.out.println("异步任务结果:" + result);} }
package com.example;import java.util.concurrent.CountDownLatch;public class CountDownLatchTest {public static void main(String[] args) throws InterruptedException {final int threadCount = 3;CountDownLatch countDownLatch = new CountDownLatch(threadCount);for (int i = 0; i < threadCount; i++) {new Thread(() -> {System.out.println("线程" + Thread.currentThread().getName() + "开始执行");try {// 模拟线程执行任务Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("线程" + Thread.currentThread().getName() + "执行完毕");countDownLatch.countDown(); // 线程执行完毕,计数减1}).start();}// 主线程等待所有线程执行完毕countDownLatch.await();System.out.println("所有线程执行完毕");} }
-
分别运行每个类,查看输出结果。
-
解释如下
-
ThreadTest:演示了如何通过实现
Runnable
接口和继承Thread
类来创建线程。 -
SynchronizedTest:演示了如何使用
synchronized
关键字来确保线程安全。 -
ExecutorServiceTest:演示了如何使用
ExecutorService
线程池来管理线程。 -
FutureTest:演示了如何使用
Future
来处理异步任务。 -
CountDownLatchTest:演示了如何使用
CountDownLatch
来同步多个线程。