赞
踩
Switch语句可以使用原始类型或枚举类型。
Java引入了另一种类型,可以在switch语句中使用:字符串类型。
public class switchAddString {
public static void main(String[] args) {
String s = "a";
switch (s) {
case "a":
System.out.println("a");
break;
case "b":
System.out.println("b");
break;
default:
System.out.println("default");
}
}
}
编译器在编译时的处理情形
case
和default
,则直接转换为if…else…
。case
。先将String转换为hashCode
,然后相应的进行处理。public static void main(String[] args) { int i = 10; System.out.println("i=" + i); // 二进制 int j = 0b1010; // 十六进制 int k = 0x1234; // 1,000,000 int l = 1_000_000; // 1,000,000 int m = 1__000_000; System.out.println("j=" + j); System.out.println("k=" + k); System.out.println("l=" + l); System.out.println("m=" + m); }
finally
中关闭socket
、文件、数据库连接等资源。try-with-resources
,用于确保资源在使用后能够正确地关闭。try-with-resources
时,你可以在 try 关键字后面的括号中声明一个或多个资源。AutoCloseable
接口(Java 7引入的接口,它具有一个 close()
方法用于释放资源)。public static void main(String[] args) { // 捕获多个异常 try { int a = 10; int b = 0; System.out.println("a/b=" + (a / b)); } catch (ArithmeticException | NullPointerException e) { e.printStackTrace(); } // try-with-resources,在 try 关键字后面的括号中声明一个或多个资源,每个资源用逗号分隔 String fileName = "example.txt"; try ( // 使用try-with-resources声明BufferedReader资源 BufferedReader reader = new BufferedReader(new FileReader(fileName)); // 需要声明多个资源,我们只需在括号中用逗号分隔 BufferedReader reader1 = new BufferedReader(new FileReader("file1.txt")); BufferedReader reader2 = new BufferedReader(new FileReader("file2.txt")) ) { // 读取文件内容 String line; while ((line = reader.readLine()) != null) { System.out.println(line); } // 这里不需要显式调用reader.close(),因为try-with-resources会自动处理 } catch (IOException e) { // 处理可能发生的IOException e.printStackTrace(); } // 在try代码块执行完毕后,reader会被自动关闭 }
<>
来省略类型参数。public static void main(String[] args) {
// Java7之前
ArrayList<String> arrayList = new ArrayList<String>();
// Java7之后
ArrayList<String> arrayList2 = new ArrayList<>();
// 泛型类
class Generic<T> {
// 构造函数参数为泛型类型
public Generic(T t) {
}
}
// 使用泛型实例化类型推断
Generic<String> generic = new Generic<>("abc");
}
Java 7 引入了 NIO 2.0(New I/O),其中包含对异步 I/O(AIO)的支持,这是一个显著的新特性,特别是在处理非阻塞 I/O 操作时非常有用。具体来说,NIO 2.0 的 AIO 支持通过引入
AsynchronousFileChannel
类来实现异步文件 I/O 操作。
public static void main(String[] args) throws Exception { // 异步读取文件 Path path = Paths.get("file.txt"); AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open( path, StandardOpenOption.READ); // 分配缓冲区 ByteBuffer buffer = ByteBuffer.allocate(1024); // 读取文件 long position = 0; // 异步读取数据,用于检查读取操作的状态和获取读取的结果 Future<Integer> operation = fileChannel.read(buffer, position); while (!operation.isDone()) { // 等待读取完成 Thread.sleep(1000); } // 读取完成,将缓冲区数据翻转 buffer.flip(); // 读取数据 byte[] data = new byte[buffer.limit()]; // 将缓冲区数据复制到data中 buffer.get(data); System.out.println(new String(data)); // 关闭文件 fileChannel.close(); }
public static void main(String[] args) throws Exception { // 创建异步通道 AsynchronousServerSocketChannel serverChannel = AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(8080)); // 接受连接 serverChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() { /** * 接受连接完成时调用此方法。 * @param clientChannel * @param attachment */ @Override public void completed(AsynchronousSocketChannel clientChannel, Void attachment) { // 继续接受连接 serverChannel.accept(null, this); // 读取数据 ByteBuffer buffer = ByteBuffer.allocate(1024); // 异步读取数据 clientChannel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() { /** * 当读取操作完成时调用此方法。 * * @param result 读取操作的结果,通常为读取的字节数,但在此处未使用 * @param attachment 包含读取数据的ByteBuffer对象 */ @Override public void completed(Integer result, ByteBuffer attachment) { // 处理读取完成 attachment.flip(); // 读取数据 byte[] data = new byte[attachment.limit()]; // 将数据复制到数组中 attachment.get(data); System.out.println(new String(data)); } /** * 读取操作失败时调用此方法。 * @param exc * @param attachment */ @Override public void failed(Throwable exc, ByteBuffer attachment) { // 处理读取失败 } }); } /** * 接受连接失败时调用此方法。 * @param exc * @param attachment */ @Override public void failed(Throwable exc, Void attachment) { // 处理接受连接失败 } }); // 程序继续执行其他操作 Thread.sleep(Long.MAX_VALUE); }
SR-292
是 Java 7 中引入的一个改进,主要针对 switch
语句的性能优化。switch
语句的效率问题在于它通过逐个比较每个 case
条件来确定执行的分支,如果分支很多,这个过程可能会很慢。switch
语句的 case
常量之间的距离非常小(称为 “small ranges
”),Java 编译器会使用一种更有效的查找方式,而不是简单的逐个比较。switch
语句的执行速度,特别是在处理密集的条件分支时。public static void main(String[] args) { int month = 3; String monthName; // Java 7 的 SR-292 特性可以在一些情况下优化这样的 switch 语句,尤其是在 case 常量的范围较小时 switch (month) { case 1: monthName = "January"; break; case 2: monthName = "February"; break; case 3: monthName = "March"; break; case 4: monthName = "April"; break; case 5: monthName = "May"; break; case 6: monthName = "June"; break; default: monthName = "Unknown"; break; } System.out.println("Month: " + monthName); }
InvokeDynamic
是 Java 7
引入的另一个重要特性,它是 Java 虚拟机(JVM
)层面的改进,旨在支持更灵活和高效的动态语言实现。Java 8
的 Lambda
表达式依赖于 InvokeDynamic
来生成相应的字节码。public static void main(String[] args) throws Throwable { // 创建动态调用 MethodHandles.Lookup lookup = MethodHandles.lookup(); // 创建方法句柄,使用lookup对象来查找Math.class中的静态方法sqrt,该方法接受一个double参数并返回一个dou* 第一个参数是`lookup`对象。 MethodHandle mh = lookup.findStatic(Math.class, "sqrt", MethodType.methodType(double.class, double.class)); // 创建动态调用 // 第一个参数是`lookup`对象 // 第二个参数是方法名,这里使用`"apply"`,因为它是`Function`接口中唯一的方法。 // 第三个参数是`Function`接口的签名(即`Function.class`的类型)。 // 第四个参数是`mh`的泛型类型签名。 // 第五个参数是我们要调用的方法句柄(即`mh`)。 // 第六个参数是`mh`的类型签名,表示我们要调用的方法的实际类型。 CallSite sqrt = LambdaMetafactory.metafactory( lookup, "apply", MethodType.methodType(Function.class), mh.type().generic(), mh, mh.type() ); // 调用动态调用 MethodHandle factory = sqrt.getTarget(); // 调用工厂方法,得到一个Function对象,使用了强制类型转换,因为factory.invoke()返回的是一个Object Function<Double, Double> sqrtFunc = (Function<Double, Double>) factory.invoke(); double result = sqrtFunc.apply(16.0); System.out.println("Square root of 16: " + result); }
在 Java 7 之前,通常使用
java.io.File
类来处理文件路径,Java 7 引入了java.nio.file.Path
接口,它是 Java 中操作文件和目录路径的抽象表示。Path
接口提供了更多功能和更强大的操作能力。
Path
接口的一些主要特性和用法:
路径表示:
Path
接口可以表示文件系统中的路径,可以是文件或目录。它不仅仅是一个字符串,而是一个真正的对象,提供了丰富的方法来操作路径。创建路径:
可以使用Paths 类的静态方法来创建 Path 对象
Path path = Paths.get("/path/to/file.txt");
路径操作:
toString()
:将路径转换为字符串表示。getFileName()
:获取路径中的文件名部分。getParent()
:获取路径中的父路径。getRoot()
:获取路径的根部分。getNameCount()
:获取路径中的名称元素的数量。subpath(int beginIndex, int endIndex)
:获取指定范围内的子路径。路径解析:
resolve()
方法可以用于解析相对路径或者连接两个路径,返回一个新的路径对象。检查路径属性:
Files
类的静态方法来检查文件或目录的属性,例如是否存在、是否可读、是否可写等。文件操作:
Files
类结合 Path
接口提供了丰富的文件操作功能,包括读取文件内容、写入文件、复制、移动、删除等。路径迭代:
Path接口支持迭代,可以方便地遍历路径的各个部分。
for (Path element : path) {
System.out.println(element);
}
相对路径和绝对路径:
Path
接口可以表示相对路径和绝对路径,并提供了方法来转换和处理这两种路径。public static void main(String[] args) { // 创建一个 Path 对象 Path path = Paths.get("/path/to/file.txt"); // 获取文件名 Path fileName = path.getFileName(); System.out.println("File Name: " + fileName); // 获取父路径 Path parent = path.getParent(); System.out.println("Parent Path: " + parent); // 获取路径的根部分 Path root = path.getRoot(); System.out.println("Root of the path: " + root); // 获取路径的元素数量 int nameCount = path.getNameCount(); System.out.println("Number of elements in the path: " + nameCount); // 遍历路径的每个元素 System.out.println("Elements in the path:"); for (int i = 0; i < nameCount; i++) { System.out.println("Element " + i + ": " + path.getName(i)); } // 路径解析示例 Path resolvedPath = path.resolve("subdir"); System.out.println("Resolved Path: " + resolvedPath); // 检查文件或目录的属性 // 判断文件是否存在 boolean exists = Files.exists(path); System.out.println("Exists: " + exists); // 判断文件是否是目录 boolean isReadable = Files.isReadable(path); System.out.println("Readable: " + isReadable); // 判断文件是否是可写 boolean isWritable = Files.isWritable(path); System.out.println("Writable: " + isWritable); // 读取文件内容 Path filePath = Paths.get("/path/to/file.txt"); List<String> lines = null; try { lines = Files.readAllLines(filePath, StandardCharsets.UTF_8); } catch (IOException e) { throw new RuntimeException(e); } for (String line : lines) { System.out.println(line); } // 写入文件内容 Path newFilePath = Paths.get("/path/to/newfile.txt"); String content = "Hello, Java 7!"; try { Files.write(newFilePath, content.getBytes()); } catch (IOException e) { throw new RuntimeException(e); } // 复制文件 Path copiedFilePath = Paths.get("/path/to/copiedfile.txt"); try { Files.copy(filePath, copiedFilePath, StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { throw new RuntimeException(e); } // 移动文件 Path targetPath = Paths.get("/path/to/targetdir/movedfile.txt"); try { Files.move(filePath, targetPath, StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { throw new RuntimeException(e); } // 删除文件 try { Files.delete(filePath); } catch (IOException e) { throw new RuntimeException(e); } }
Java 7 引入了
Fork/Join
框架,是一种并行计算框架,专门用于解决分而治之的问题。主要用于执行递归式地将问题划分为更小子问题,并行执行这些子问题的计算,然后合并结果的任务。
使用 Fork/Join 框架的基本步骤:
RecursiveTask
或 RecursiveAction
):
RecursiveTask
: 用于有返回值的任务。RecursiveAction
: 用于无返回值的任务。compute()
方法:
compute()
方法来定义任务的具体执行逻辑。ForkJoinPool
类来管理并发执行的任务。ForkJoinPool.commonPool()
方法来获取默认的线程池,也可以根据需要创建自定义的线程池。ForkJoinPool
来执行。使用 Fork/Join
框架来计算数组的总和Demo:
import java.util.concurrent.*; // 继承 RecursiveTask 来实现有返回值的任务 class SumTask extends RecursiveTask<Long> { // 阈值,控制任务拆分的粒度 private static final int THRESHOLD = 10; private int[] array; private int start; private int end; public SumTask(int[] array, int start, int end) { this.array = array; this.start = start; this.end = end; } @Override protected Long compute() { if (end - start <= THRESHOLD) { // 如果任务足够小,直接计算结果 long sum = 0; for (int i = start; i < end; i++) { sum += array[i]; } return sum; } else { // 否则,拆分任务为更小的子任务 int mid = (start + end) / 2; SumTask leftTask = new SumTask(array, start, mid); SumTask rightTask = new SumTask(array, mid, end); // 异步执行左边的子任务 leftTask.fork(); // 同步执行右边的子任务 long rightResult = rightTask.compute(); // 获取左边子任务的结果 long leftResult = leftTask.join(); // 合并子任务的结果 return leftResult + rightResult; } } } public class ForkJoinDemo { public static void main(String[] args) { int[] array = new int[100]; for (int i = 0; i < array.length; i++) { array[i] = i; } // 创建 Fork/Join 线程池 ForkJoinPool forkJoinPool = ForkJoinPool.commonPool(); // 创建任务并提交给 Fork/Join 线程池 SumTask task = new SumTask(array, 0, array.length); long result = forkJoinPool.invoke(task); // 输出计算结果 System.out.println("Sum: " + result); } }
如果你累了,学会休息,而不是放弃
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。