讲解JDK从8以后(包含8)各个版本的各种新特性
xsobi 2024-12-17 17:06 2 浏览
1. JDK
JDK 全称 Java Development Kit,是 Java 开发环境。我们通常所说的 JDK 指的是 Java SE (Standard Edition) Development Kit。除此之外还有 Java EE(Enterprise Edition)和 Java ME(Micro Edition platforms)。
1.1 Java 的发布周期
版本 | 发布时间 | 名称 |
JDK Beta | 1995 | WebRunner |
JDK 1.0 | 1996.1 | Oak |
JDK 1.1 | 1997.2 | |
J2SE 1.2 | 1998.12 | playground |
J2SE 1.3 | 2000.5 | Kestrel |
J2SE 1.4 | 2002.2 | Merlin |
J2SE 5.0 | 2004.9 | Tiger |
Java SE 6 | 2006.12 | Mustang |
Java SE 7 | 2011.7 | Dolphin |
Java SE 8(Lts) | 2014.3 | |
Java SE 9 | 2017.9 | |
Java SE 10 | 2018.3 | |
Java SE 11(Lts) | 2018.9 | |
Java SE 12 | 2019.3 | |
Java SE 13 | 2019.9 | |
Java SE 14 | 2020.3 | |
Java SE 15 | 2020.9 |
1.2 Java发展过程中的重要节点
1995年: alpha 和 beta Java 公开版本发布,取名为 WebRunner。
1996年: Java 第一个版本发布,取名叫 Oak。但是第一个稳定版本是 JDK 1.0.2,被称做 Java 1。
1998.12.8: 发布了 J2SE 1.2。这个版本到 J2SE 5.0 更名为 Java 2。其中的 SE 指的是 Standard Edition,为了区别于 J2EE(Enterprise Edition)和 J2ME(Micro Edition)。
2000.5: 发布了 J2SE 1.3,其中包含了 HotSpot JVM。而 HotSpot JVM 首次发布是在 1999.4,名为 J2SE 1.2 JVM。
2004.9.30: 发布了 J2SE 5.0。为什么这个版本命名和前面几个版本不一样呢?这个版本原本计划以 1.5 命名的,沿用以前的命名方式。但是为了更好的反映这个版本的成熟度,所以改名为 5.0。
这个版本以后,有了一个新的版本控制系统,5.0 用来表示产品版本,用来表示稳定的 J2SE 版本,而 1.5.0 用来表示开发者版本,也就是 Java 5.0 = JDK 1.5.0。
2006.12.11: J2SE 改名为 Java SE,版本号去掉了 .0。此后对应版本就是 Java 6 = JDK 1.6,Java 7 = JDK 1.7。
2011.7.7: 发布 Java SE 7,是一个重大版本更新。更新了众多特性。
2018.3: 发布 Java SE 10。在此之前,Java 基本上是两年一个版本,除了 Java SE 7 经过了五年,Java SE 8 经过了三年。在此之后,就是每六个月发布一次新版本。但是不是每个版本都是 LTS(Long-Term-Support)。按照 Oracle 的计划,每三年会有一个 LTS 版本。最近的 LTS 版本就是 Java SE 11 了。
2. Java SE 8后各个版本介绍
2.1 Java SE 8
2.1.1. Lambda 和 函数式接口 Lambda 表达式相信不用再过多的介绍,终于在 Java 8 引入了,可以极大的减少代码量,代码看起来更清爽。
函数式接口就是有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。可以隐式转化为 Lambda 表达式。
我们定义一个函数式接口如下:
@FunctionalInterface
interface Operation {
int operation(int a, int b);
}
// 再定义一个 Class 用来操作 Operation 接口。
class Test {
private int operate(int a, int b, Operation operation) {
return operation.operation(a, b);
}
}
Test test = new Test();
// 在 Java 8 之前,我们想要实现 Operation 接口并传给 Test.operate() 方法使用,我们要定义一个匿名类,实现 Operation 方法。
test.operate(1, 2, new Operation() {
@Override
public int operation(int a, int b) {
return a + b;
}
});
// 而使用 Lambda 表达式,我们就可以这样写了:
test.operate(1, 2, (a, b) -> a + b);
复制代码
2.1.2 方法推导
通过方法引用,可以使用方法的名字来指向一个方法。使用一对冒号来引 "::" 用方法。还是以上面的例子来看,我们再添加几个方法:
@FunctionalInterface
interface Operation {
int operation(int a, int b);
}
interface Creater<T> {
T get();
}
interface TestInt {
int cp(Test test1, Test test2);
}
class Test {
public static Test create(Creater<Test> creater) {
return creater.get();
}
private int operate(int a, int b, Operation operation) {
return operation.operation(a, b);
}
private static int add(int a, int b) {
return a + b;
}
private int sub(int a, int b) {
return a - b;
}
public int testM(Test test) {
return 0;
}
public void test(TestInt testInt) {
Test t1 = Test.create(Test::new);
Test t2 = Test.create(Test::new);
testInt.cp(t1, t2);
}
}
复制代码
那么对应的方法引用有四种:
- 构造方法引用
使用方式:Class::new
Test test = Test.create(Test::new);
复制代码
- 静态方法引用
使用方式:Class::staticMethod
test.operate(1, 2, Test::add);
复制代码
- 对象的实例方法引用
使用方式:instance::method
test.operate(1, 2, test::sub);
复制代码
- 类的实例方法引用
使用方式:Class::method
test.test(Test::testM);
复制代码
其实上面三种方法引用都好理解,最后类的实例方法引用,有两个条件:
- 首先要满足实例方法,而不是静态方法
- Lambda 表达式的第一个参数会成为调用实例方法的对象
根据这两点我们看上面的例子,test 方法接受一个 TestInt 实例,用 Lambda 表达式表示就是 (Test t1, Test t2) -> res,而我们调用 test 方法时传入的方法引用是 Test::testM,其参数也是一个 Test 实例,最终 test.test(Test::testM) 的调用效果就是 t1.testM(t2)
2.1.3 接口默认方法和静态方法
Java 8 新增了接口的默认实现,通过 default 关键字表示。同时也可以提供静态默认方法。
public interface TestInterface {
String test();
// 接口默认方法
default String defaultTest() {
return "default";
}
static String staticTest() {
return "static";
}
}
复制代码
2.1.4 重复注解
Java 8 支持了重复注解。在 Java 8 之前想实现重复注解,需要用一些方法来绕过限制。比如下面的代码。
@interface Author {
String name();
}
@interface Authors {
Author[] value();
}
@Authors({@Author(name="a"), @Author(name = "b")})
class Article {
}
复制代码
而在 Java 8 中,可以直接用下面的方式。
@Repeatable(Authors.class)
@interface Author {
String name();
}
@interface Authors {
Author[] value();
}
@Author(name = "a")
@Author(name = "b")
class Article {
}
复制代码
在解析注解的时候,Java 8 也提供了新的 API。
AnnotatedElement.getAnnotationsByType(Class<T>)
复制代码
2.1.5 类型注解
Java 8 之前注解只能用在声明中,在 Java 8 中,注解可以使用在 任何地方。
@Author(name="a")
private Object name = "";
private String author = (@Author(name="a")String) name;
复制代码
2.1.6 更好的类型推断
Java 8 对于类型推断做了改进。
比如在 Java 7 中下面的写法:
List<String> stringList = new ArrayList<>();
stringList.add("A");
stringList.addAll(Arrays.<String>asList());
复制代码
在 Java 8 中改进后的写法,可以自动做类型推断。
List<String> stringList = new ArrayList<>();
stringList.add("A");
stringList.addAll(Arrays.asList());
复制代码
2.1.7 Optional
Java 8 中新增了 Optional 类用来解决空指针异常。Optional 是一个可以保存 null 的容器对象。通过 isPresent() 方法检测值是否存在,通过 get() 方法返回对象。
除此之外,Optional 还提供了很多其他有用的方法,具体可以查看文档。下面是一些示例代码。
// 创建一个 String 类型的容器
Optional<String> str = Optional.of("str");
// 值是否存在
boolean pre = str.isPresent();
// 值如果存在就调用 println 方法,这里传入的是 println 的方法引用
str.ifPresent(System.out::println);
// 获取值
String res = str.get();
// 传入空值
str = Optional.ofNullable(null);
// 如果值存在,返回值,否则返回传入的参数
res = str.orElse("aa");
str = Optional.of("str");
// 如果有值,对其调用映射函数得到返回值,对返回值进行 Optional 包装并返回
res = str.map(s -> "aa" + s).get();
// 返回一个带有映射函数的 Optional 对象
res = str.flatMap(s -> Optional.of(s + "bb")).flatMap(s -> Optional.of(s + "cc")).get();
复制代码
2.1.8 Stream
Java 8 中新增的 Stream 类提供了一种新的数据处理方式。这种方式将元素集合看做一种流,在管道中传输,经过一系列处理节点,最终输出结果。
关于 Stream 提供的具体方法,可以参照 API。下面是一些示例代码。
List<String> list = Arrays.asList("maa", "a", "ab", "c");
list.stream()
.filter(s -> s.contains("a"))
.map(s -> s + "aa")
.sorted()
.forEach(System.out::println);
System.out.println("####");
list.parallelStream().forEach(System.out::println);
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
int res = numbers.stream().map(i -> i + 1).mapToInt(i -> i).summaryStatistics().getMax();
System.out.println(res);
复制代码
2.1.9 日期时间 API
Java 8 中新增了日期时间 API 用来加强对日期时间的处理,其中包括了 LocalDate,LocalTime,LocalDateTime,ZonedDateTime 等等,关于 API 可以参照官方文档以及这篇博客,写的很详细。
www.cnblogs.com/muscleape/p…
下面是示例代码。
LocalDate now = LocalDate.now();
System.out.println(now);
System.out.println(now.getYear());
System.out.println(now.getMonth());
System.out.println(now.getDayOfMonth());
LocalTime localTime = LocalTime.now();
System.out.println(localTime);
LocalDateTime localDateTime = now.atTime(localTime);
System.out.println(localDateTime);
复制代码
2.1.10 Base64 支持
Java 8 标准库中提供了对 Base 64 编码的支持。具体 API 见可参照文档。下面是示例代码。
String base64 = Base64.getEncoder().encodeToString("aaa".getBytes());
System.out.println(base64);
byte[] bytes = Base64.getDecoder().decode(base64);
System.out.println(new String(bytes));
复制代码
2.1.11 并行数组 ParallelSort
Java 8 中提供了对数组的并行操作,包括 parallelSort 等等,具体可参照 API。 Arrays.parallelSort(new int[] {1, 2, 3, 4, 5});
2.1.12 其他特性
- 对并发的增强
- 在java.util.concurrent.atomic包中还增加了下面这些类:
DoubleAccumulator DoubleAdder LongAccumulator LongAdder
- 提供了新的 Nashorn javascript 引擎
- 提供了 jjs,是一个给予 Nashorn 的命令行工具,可以用来执行 JavaScript 源码
- 提供了新的类依赖分析工具 jdeps
- JVM 的新特性
JVM内存永久区已经被metaspace替换(JEP 122)。JVM参数 -XX:PermSize 和 –XX:MaxPermSize被XX:MetaSpaceSize 和 -XX:MaxMetaspaceSize代替。 可以看到,Java 8 整体上的改进是很大的,最重要的是引入 Lambda 表达式,简化代码。
其他一些改进可参照:
www.oracle.com/technetwork…
2.2 Java SE 9
2.2.1 Jigsaw 模块系统
在 Java 9 以前,打包和依赖都是基于 JAR 包进行的。JRE 中包含了 rt.jar,将近 63M,也就是说要运行一个简单的 Hello World,也需要依赖这么大的 jar 包。在 Java 9 中提出的模块化系统,对这点进行了改善。
关于模块化系统具体可以看看这篇文章。
zhuanlan.zhihu.com/p/24800180
2.2.2 JShell REPL
Java 9 提供了交互式解释器。有了 JShell 以后,Java 终于可以像 Python,Node.js 一样在 Shell 中运行一些代码并直接得出结果了。
2.2.3 私有接口方法,接口中使用私有方法
Java 9 中可以在接口中定义私有方法。示例代码如下:
public interface TestInterface {
String test();
// 接口默认方法
default String defaultTest() {
pmethod();
return "default";
}
private String pmethod() {
System.out.println("private method in interface");
return "private";
}
}
复制代码
2.2.4 集合不可变实例工厂方法
在以前,我们想要创建一个不可变的集合,需要先创建一个可变集合,然后使用 unmodifiableSet 创建不可变集合。代码如下:
Set<String> set = new HashSet<>();
set.add("A");
set.add("B");
set.add("C");
set = Collections.unmodifiableSet(set);
System.out.println(set);
复制代码
Java 9 中提供了新的 API 用来创建不可变集合。
List<String> list = List.of("A", "B", "C");
Set<String> set = Set.of("A", "B", "C");
Map<String, String> map = Map.of("KA", "VA", "KB", "VB");
复制代码
2.2.5 改进 try-with-resources
Java 9 中不需要在 try 中额外定义一个变量。Java 9 之前需要这样使用 try-with-resources:
InputStream inputStream = new StringBufferInputStream("a");
try (InputStream in = inputStream) {
in.read();
} catch (IOException e) {
e.printStackTrace();
}
复制代码
在 Java 9 中可以直接使用 inputStream 变量,不需要再额外定义新的变量了。
InputStream inputStream = new StringBufferInputStream("a");
try (inputStream) {
inputStream.read();
} catch (IOException e) {
e.printStackTrace();
}
复制代码
2.2.6 多版本兼容 jar 包
Java 9 中支持在同一个 JAR 中维护不同版本的 Java 类和资源。
2.2.7 增强了 Stream,Optional,Process API
2.2.8 新增 HTTP2 Client
2.2.9 增强 Javadoc,增加了 HTML 5 文档的输出,并且增加了搜索功能
2.2.10 增强 @Deprecated
对 Deprecated 新增了 since 和 forRemoval 属性
2.2.11 增强了钻石操作符 "<>",可以在 匿名内部类中使用了。
在 Java 9 之前,内部匿名类需要指定泛型类型,如下:
Handler<? extends Number> intHandler1 = new Handler<Number>(2) {
}
复制代码
而在 Java 9 中,可以自动做类型推导,如下:
Handler<? extends Number> intHandler1 = new Handler<>(2) {
}
复制代码
2.2.12 多分辨率图像 API:定义多分辨率图像API,开发者可以很容易的操作和展示不同分辨率的图像了。
2.2.13 改进的 CompletableFuture API
CompletableFuture 类的异步机制可以在 ProcessHandle.onExit 方法退出时执行操作。 其他一些改进可参照:
docs.oracle.com/javase/9/wh…
2.3 Java SE 10
2.3.1 新增局部类型推断 var
var a = "aa";
System.out.println(a);
复制代码
var 关键字目前只能用于局部变量以及 for 循环变量声明中。
2.3.2 删除工具 javah
从JDK中移除了 javah 工具,使用 javac -h 代替。
2.3.3 统一的垃圾回收接口,改进了 GC 和其他内务管理
其他特性
ThreadLocal 握手交互 JDK 10 引入一种在线程上执行回调的新方法,很方便的停止单个线程而不是停止全部线程或者一个都不停。
基于Java的实验性JIT编译器 Java 10 开启了 Java JIT编译器 Graal,用作Linux / x64平台上的实验性JIT编译器。
提供默认的 CA 根证书
将 JDK 生态整合到单个仓库 此JEP的主要目标是执行一些内存管理,并将JDK生态的众多存储库组合到一个存储库中。
其他一些改进可以参照:
www.oracle.com/technetwork…
2.4 Java SE 11
2.4.1 Lambda 中使用 var
(var x, var y) -> x.process(y)
复制代码
2.4.2 字符串 API 增强
Java 11 新增了 一系列字符串处理方法,例如:
// 判断字符串是否为空白
" ".isBlank();
" Javastack ".stripTrailing(); // " Javastack"
" Javastack ".stripLeading(); // "Javastack "
复制代码
2.4.3 标准化 HttpClient API
2.4.4 java 直接编译并运行,省去先 javac 编译生成 class 再运行的步骤
2.4.5 增加对 TLS 1.3 的支持
2.4.6 添加了新的垃圾收集器ZGC,不过只是实验性引入
Z垃圾收集器(也称为ZGC)是可伸缩的低延迟垃圾收集器(JEP 333)。它旨在满足以下目标:
- 暂停时间不超过10毫秒
- 暂停时间不会随着堆或活动集的大小而增加
- 处理大小从几百兆字节到几兆兆字节的堆
ZGC的核心是并发的垃圾收集器,这意味着在Java线程继续执行的同时,所有繁重的工作(标记,压缩,参考处理,字符串表清理等)都已完成。这极大地限制了垃圾回收对应用程序响应时间的负面影响。 ZGC的实验版本具有以下限制:
- 仅在Linux / x64上可用。
- 不支持使用压缩的oop和/或压缩的类点。在-XX:+UseCompressedOops和-XX:+UseCompressedClassPointers选项默认为禁用。启用它们将无效。
- 不支持类卸载。在-XX:+ClassUnloading和-XX:+ClassUnloadingWithConcurrentMark选项默认为禁用。启用它们将无效。
- 不支持将ZGC与Graal结合使用。
其他一些改进可以参照:
www.oracle.com/technetwork…
2.5 Java SE 12
2.5.1 switch 表达式
Java 12 以后,switch 不仅可以作为语句,也可以作为表达式。
private String switchTest(int i) {
return switch (i) {
case 1 -> "1";
default -> "0";
};
}
复制代码
其他一些改进可以参照:
www.oracle.com/technetwork…
2.6 Java SE 13
2.6.1 使用归档方式启动
在使用归档文件启动时,JVM 将归档文件映射到其对应的内存中,其中包含所需的大多数类,而需要使用多么复杂的类加载机制。甚至可以在并发运行的 JVM 实例之间共享内存区域,通过这种方式可以释放需要在每个 JVM 实例中创建相同信息时浪费的内存,从而节省了内存空间。 在 Java 12 中,默认开启了对 JDK 自带 JAR 包类的存档,如果想关闭对自带类库的存档,可以在启动参数中加上:
-Xshare:off
复制代码
而在 Java 13 中,可以不用提供归档类列表,而是通过更简洁的方式来创建包含应用程序类的归档。具体可以使用参数 -XX:ArchiveClassesAtExit 来控制应用程序在退出时生成存档,也可以使用 -XX:SharedArchiveFile 来使用动态存档功能,详细使用见如下示例。 创建存档文件示例
$ java -XX:ArchiveClassesAtExit=helloworld.jsa -cp helloworld.jar Hello
复制代码
使用存档文件示例
$ java -XX:SharedArchiveFile=hello.jsa -cp helloworld.jar Hello
复制代码
上述就是在 Java 应用程序执行结束时动态进行类归档,并且在 Java 10 的基础上,将多条命令进行了简化,可以更加方便地使用类归档功能。
2.6.2 Switch 表达式扩展(预览功能)
在 Java 12 中引入了 Switch 表达式作为预览特性,而在 Java 13 中对 Switch 表达式做了增强改进,在块中引入了 yield 语句来返回值,而不是使用 break。这意味着,Switch 表达式(返回值)应该使用 yield,而 Switch 语句(不返回值)应该使用 break,而在此之前,想要在 Switch 中返回内容,还是比较麻烦的,只不过目前还处于预览状态。 在 Java 13 之后,Switch 表达式中就多了一个关键字用于跳出 Switch 块的关键字 yield,主要用于返回一个值,它和 return 的区别在于:return 会直接跳出当前循环或者方法,而 yield 只会跳出当前 Switch 块,同时在使用 yield 时,需要有 default 条件。 在 Java 12 之前,传统 Switch 语句写法为:
传统形式
private static String getText(int number) {
String result = "";
switch (number) {
case 1, 2:
result = "one or two";
break;
case 3:
result = "three";
break;
case 4, 5, 6:
result = "four or five or six";
break;
default:
result = "unknown";
break;
};
return result;
}
复制代码
在 Java 12 之后,关于 Switch 表达式的写法改进为如下:
标签简化形式
private static String getText(int number) {
String result = switch (number) {
case 1, 2 -> "one or two";
case 3 -> "three";
case 4, 5, 6 -> "four or five or six";
default -> "unknown";
};
return result;
}
复制代码
而在 Java 13 中,,value break 语句不再被编译,而是用 yield 来进行值返回,上述写法被改为如下写法: yield 返回值形式
private static String getText(int number) {
return switch (number) {
case 1, 2:
yield "one or two";
case 3:
yield "three";
case 4, 5, 6:
yield "four or five or six";
default:
yield "unknown";
};
}
复制代码
2.6.3 文本块(预览功能)
一直以来,Java 语言在定义字符串的方式是有限的,字符串需要以双引号开头,以双引号结尾,这导致字符串不能够多行使用,而是需要通过换行转义或者换行连接符等方式来变通支持多行,但这样会增加编辑工作量,同时也会导致所在代码段难以阅读、难以维护。
Java 13 引入了文本块来解决多行文本的问题,文本块以三重双引号开头,并以同样的以三重双引号结尾终止,它们之间的任何内容都被解释为字符串的一部分,包括换行符,避免了对大多数转义序列的需要,并且它仍然是普通的 java.lang.String 对象,文本块可以在 Java 中可以使用字符串文字的任何地方使用,而与编译后的代码没有区别,还增强了 Java 程序中的字符串可读性。并且通过这种方式,可以更直观地表示字符串,可以支持跨越多行,而且不会出现转义的视觉混乱,将可以广泛提高 Java 类程序的可读性和可写性。
在 Java 13 之前,多行字符串写法为:
多行字符串写法
String html ="<html>\n" +
" <body>\n" +
" <p>Hello, World</p>\n" +
" </body>\n" +
"</html>\n";
String json ="{\n" +
" \"name\":\"mkyong\",\n" +
" \"age\":38\n" +
"}\n";
复制代码
在 Java 13 引入文本块之后,写法为:
多行文本块写法
String html = """
<html>
<body>
<p>Hello, World</p>
</body>
</html>
""";
String json = """
{
"name":"mkyong",
"age":38
}
""";
复制代码
文本块是作为预览功能引入到 Java 13 中的,这意味着它们不包含在相关的 Java 语言规范中,这样做的好处是方便用户测试功能并提供反馈,后续更新可以根据反馈来改进功能,或者必要时甚至删除该功能,如果该功能立即成为 Java SE
准的一部分,则进行更改将变得更加困难。重要的是要意识到预览功能不是 beta 形式。
由于预览功能不是规范的一部分,因此有必要为编译和运行时明确启用它们。需要使用下面两个命令行参数来启用预览功能:
清单 8. 启用预览功能
$ javac --enable-preview --release 13 Example.java
$ java --enable-preview Example
复制代码
2.7 Java SE 14
2.7.1 instanceof模式匹配
通常情况下我们使用instanceof来探测类的真实类型,如果符合该类型,则可进行强制转换。
在Java14之前,我们通常的写法如下:
Object obj = "程序新视界";
if(obj instanceof String){
String str = (String) obj;
System.out.println("关注公众号:" + str);
}
复制代码
通过java14的新特性,我们可以简化成如下方式:
Object obj = "程序新视界";
if(obj instanceof String str){
System.out.println("关注公众号:" + str);
}
复制代码
我们可以通过模式匹配简洁地表达对象,并允许各种语句和表达式对其进行测试。
2.7.2 记录类型(Record Type)的引入
Java 14中记录类型(Record Type)作为预览特性被引入。记录对象允许使用紧凑的语法来声明类,和枚举类型一样,记录也是类的一种受限形式。
在idea 2020.1中,创建Record与创建类和枚举一样,可以在创建时直接选择对应的类型。
定义一个Record类型如下:
public record Point(int x, int y) {
}
复制代码
使用Record操作如下:
Point point = new Point(1,3);
System.out.println(point.x());
System.out.println(point.y());
复制代码
对Record类进行反编译我们会看到如下内容:
public final class Point extends java.lang.Record {
private final int x;
private final int y;
public Point(int x, int y) { /* compiled code */ }
public java.lang.String toString() { /* compiled code */ }
public final int hashCode() { /* compiled code */ }
public final boolean equals(java.lang.Object o) { /* compiled code */ }
public int x() { /* compiled code */ }
public int y() { /* compiled code */ }
}
复制代码
文章来源:https://juejin.cn/post/6930771509900214286
相关推荐
- 好用的云函数!后端低代码接口开发,零基础编写API接口
-
前言在开发项目过程中,经常需要用到API接口,实现对数据库的CURD等操作。不管你是专业的PHP开发工程师,还是客户端开发工程师,或者是不懂编程但懂得数据库SQL查询,又或者是完全不太懂技术的人,通过...
- 快速上手:Windows 平台上 cURL 命令的使用方法
-
在工作流程中,为了快速验证API接口有效性,团队成员经常转向直接执行cURL命令的方法。这种做法不仅节省时间,而且促进了团队效率的提升。对于使用Windows系统的用户来说,这里有一套详细...
- 使用 Golang net/http 包:基础入门与实战
-
简介Go的net/http包是构建HTTP服务的核心库,功能强大且易于使用。它提供了基本的HTTP客户端和服务端支持,可以快速构建RESTAPI、Web应用等服务。本文将介绍ne...
- #小白接口# 使用云函数,人人都能编写和发布自己的API接口
-
你只需编写简单的云函数,就可以实现自己的业务逻辑,发布后就可以生成自己的接口给客户端调用。果创云支持对云函数进行在线接口编程,进入开放平台我的接口-在线接口编程,设计一个新接口,设计和配置好接口参...
- 极度精神分裂:我家没有墙面开关,但我虚拟出来了一系列开关
-
本内容来源于@什么值得买APP,观点仅代表作者本人|作者:iN在之前和大家说过,在iN的家里是没有墙面开关的。...
- window使用curl命令的注意事项 curl命令用法
-
cmd-使用curl命令的注意点前言最近在cmd中使用curl命令来测试restapi,发现有不少问题,这里记录一下。在cmd中使用curl命令的注意事项json不能由单引号包括起来json...
- Linux 系统curl命令使用详解 linuxctrl
-
curl是一个强大的命令行工具,用于在Linux系统中进行数据传输。它支持多种协议,包括HTTP、HTTPS、FTP等,用于下载或上传数据,执行Web请求等。curl命令的常见用法和解...
- Tornado 入门:初学者指南 tornados
-
Tornado是一个功能强大的PythonWeb框架和异步网络库。它最初是为了处理实时Web服务中的数千个同时连接而开发的。它独特的Web服务器和框架功能组合使其成为开发高性能Web...
- PHP Curl的简单使用 php curl formdata
-
本文写给刚入PHP坑不久的新手们,作为工具文档,方便用时查阅。CURL是一个非常强大的开源库,它支持很多种协议,例如,HTTP、HTTPS、FTP、TELENT等。日常开发中,我们经常会需要用到cur...
- Rust 服务器、服务和应用程序:7 Rust 中的服务器端 Web 应用简介
-
本章涵盖使用Actix提供静态网页...
- 我给 Apache 顶级项目提了个 Bug apache顶级项目有哪些
-
这篇文章记录了给Apache顶级项目-分库分表中间件ShardingSphere提交Bug的历程。说实话,这是一次比较曲折的Bug跟踪之旅。10月28日,我们在GitHub上提...
- linux文件下载、服务器交互(curl)
-
基础环境curl命令描述...
- curl简单使用 curl sh
-
1.curl--help#查看关键字2.curl-A“(添加user-agent<name>SendUser-Agent<name>toserver)”...
- 常用linux命令:curl 常用linux命令大全
-
//获取网页内容//不加任何选项使用curl时,默认会发送GET请求来获取内容到标准输出$curlhttp://www.baidu.com//输出<!DOCTYPEh...
- 三十七,Web渗透提高班之hack the box在线靶场注册及入门知识
-
一.注册hacktheboxHackTheBox是一个在线平台,允许测试您的渗透技能和代码,并与其他类似兴趣的成员交流想法和方法。它包含一些不断更新的挑战,并且模拟真实场景,其风格更倾向于CT...
- 一周热门
- 最近发表
-
- 好用的云函数!后端低代码接口开发,零基础编写API接口
- 快速上手:Windows 平台上 cURL 命令的使用方法
- 使用 Golang net/http 包:基础入门与实战
- #小白接口# 使用云函数,人人都能编写和发布自己的API接口
- 极度精神分裂:我家没有墙面开关,但我虚拟出来了一系列开关
- window使用curl命令的注意事项 curl命令用法
- Linux 系统curl命令使用详解 linuxctrl
- Tornado 入门:初学者指南 tornados
- PHP Curl的简单使用 php curl formdata
- Rust 服务器、服务和应用程序:7 Rust 中的服务器端 Web 应用简介
- 标签列表
-
- grid 设置 (58)
- 移位运算 (48)
- not specified (45)
- patch补丁 (31)
- strcat (25)
- 导航栏 (58)
- context xml (46)
- scroll (43)
- element style (30)
- dedecms模版 (53)
- vs打不开 (29)
- nmap (30)
- webgl开发 (24)
- parse (24)
- c 视频教程下载 (33)
- paddleocr (28)
- listview排序 (33)
- firebug 使用 (31)
- transactionmanager (30)
- characterencodingfilter (33)
- getmonth (34)
- commandtimeout (30)
- hibernate教程 (31)
- label换行 (33)
- curlpost (31)