JDK17 你的下一个白月光
JDK版本升级的非常快,现在已经到JDK20了。JDK版本虽多,但应用最广泛的还得是JDK8,正所谓“他发任他发,我用Java8”。
但实际情况却不是这样,越来越多的java工程师拥抱 JDK17,于是了解了一下 JDK17新语法,感觉确实香啊,推荐大家一起试一下!
-
长期支持版本
JDK17是Oracle于2021年9月14日发布的一个长期支持版本(LTS)。它将获得长期的更新和支持,帮助保持程序的稳定性和可靠性。 -
性能提升
经过综合评估,我们发现在从Java 8升级到Java 11后,G1GC的平均速度提升了16.1%,ParallelGC则提升了4.5%。当从Java 11升级到Java 17时,G1GC的平均速度提升了8.66%,而ParallelGC则提升了6.54%。这些结果是基于对OptaPlanner用例的基准测试得出的。总的来说,这些优
化让垃圾回收器更加优秀。
最大的亮点是带来了稳定版的ZGC垃圾回收器,达到亚毫秒级停顿。 -
新语法和特性
Switch表达式简化、Text Blocks文本块、instanceof的模式匹配升级和NullPointerException提示信息改进等
支持最新的技术和框架
Spring framework6 和Spring Boot3 都默认使用 Java 17作为最低版本 -
压测结果
JDK17相对于JDK8和JDK11,所有垃圾回收器的性能都有很明显的提升,特别是稳定版的ZGC垃圾回收器。不论任何机器配置下,都推荐使用ZGC,ZGC的停顿时间达到亚毫秒级,吞吐量也比较高
一、JDK17 新语法
1. 文本块
推荐指数:⭐️⭐️⭐️⭐️⭐️
这个更新非常实用。在没有这个特性之前,编写长文本非常痛苦,充满拼接符号。现在,通过字符串块,我们可以轻松编写JSON、HTML、SQL等内容,效果更清爽。
原来的写法
/*** 使用JDK8返回HTML文本** @return 返回HTML文本*/
public static final String getHtmlJDK8() {return "<html>\n" +" <body>\n" +" <p>Hello, world</p>\n" +" </body>\n" +"</html>";
}
新的写法
/*** 使用JDK17返回HTML文本** @return 返回HTML文本*/
public static final String getHtmlJDK17() {return """<html><body><p>Hello, world</p></body></html>""";
}
2. NullPointerException增强
推荐指数:⭐️⭐️⭐️⭐️⭐️
这一功能非常强大且实用,相信每位Java开发者都期待已久。空指针异常(
NPE
)一直是Java程序员的痛点,因为报错信息无法直观地指出哪个对象为空,只抛出一个NullPointerException和一堆堆栈信息,定位问题耗时且麻烦。
Java17终于在这方面取得了突破,提供了更详细的空指针异常信息,帮助开发者迅速定位问题源头。
public static void main(String[] args) {try {//简单的空指针String str = null;str.length();} catch (Exception e) {e.printStackTrace();}try {//复杂一点的空指针var arr = List.of(null);String str = (String)arr.get(0);str.length();} catch (Exception e) {e.printStackTrace();}
}
运行结果
3. Records
推荐指数:⭐️⭐️⭐️⭐️
在Java中,POJO对象(如DO、PO、VO、DTO等)通常包含成员变量及相应的Getter和Setter方法。尽管可以通过工具或IDE生成这些代码,但修改和维护仍然麻烦。
Lombok插件为此出现,能够在编译期间自动生成Getter、Setter、hashcode、equals和构造函数等代码,使用起来方便,但对团队有依赖要求。
为此,Java引入了标准解决方案:Records。它通过 简洁的语法定义数据类,大大简化了POJO类的编写,如下所示。虽然hashcode和equals方法仍需手动编写,但IDE能够自动生成。这一特性有效解决了模板代码问题,提升了代码整洁度和可维护性。
package com.summo.jdk17;/**** @param stuId 学生ID* @param stuName 学生名称* @param stuAge 学生年龄* @param stuGender 学生性别* @param stuEmail 学生邮箱*/
public record StudentRecord(Long stuId,String stuName,int stuAge,String stuGender,String stuEmail) {public StudentRecord {System.out.println("构造函数");}public static void main(String[] args) {StudentRecord record = new StudentRecord(1L, "张三", 16, "男", "xxx@qq.com");System.out.println(record);}
}
4. 全新的switch表达式
推荐指数:⭐️⭐️⭐️
在Java12的时候就引入了switch表达式,注意这里是表达式,而不是语句,原来的switch是语句。
如果不清楚两者的区别的话,最好先去了解一下。主要的差别就是就是表达式有返回值,而语句则没有。
配合 模式匹配,以及yield和“->”符号的加入,全新的switch用起来爽到飞起来。
package com.summo.jdk17;public class SwitchDemo {/*** 在JDK8中获取switch返回值方式** @param week* @return*/public int getByJDK8(Week week) {int i = 0;switch (week) {case MONDAY, TUESDAY:i = 1;break;case WEDNESDAY:i = 3;break;case THURSDAY:i = 4;break;case FRIDAY:i = 5;break;case SATURDAY:i = 6;break;case SUNDAY:i = 7;break;default:i = 0;break;}return i;}/*** 在JDK17中获取switch返回值** @param week* @return*/public int getByJDK17(Week week) {// 1, 现在的switch变成了表达式,可以返回值了,而且支持yield和->符号来返回值// 2, 再也不用担心漏写了break,而导致出问题了// 3, case后面支持写多个条件return switch (week) {case null -> -1;case MONDAY -> 1;case TUESDAY -> 2;case WEDNESDAY -> 3;case THURSDAY -> {yield 4;}case FRIDAY -> 5;case SATURDAY, SUNDAY -> 6;default -> 0;};}private enum Week {MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY}
}
5. 私有接口方法
推荐指数:⭐️⭐️⭐️
从Java8开始,允许在interface里面添加 默认方法,但有一个问题,如果一个default方法体很大怎么办,拆到另外的类去写吗?实在有些不太合理,
所以在Java17里面,如果一个default方法体很大,那么可以通过新增接口私有方法来进行一个合理的拆分了。
public interface PrivateInterfaceMethod {/*** 接口默认方法*/default void defaultMethod() {privateMethod();}// 接口私有方法,在Java8里面是不被允许的,不信你试试private void privateMethod() {}
}
6. 模式匹配
推荐指数:⭐️⭐️⭐️⭐️
在JDK 17中,模式匹配 主要用于 instanceof 表达式。
模式匹配 增强了instanceof的语法和功能,使 类型检查 和 类型转换 更加简洁和高效。
在传统的Java版本中,我们通常使用 instanceof 结合 类型转换 来 判断对象类型 并 进行处理,这往往会导致冗长的代码。
原来的写法
/*** 旧式写法** @param value*/
public void matchByJDK8(Object value) {if (value instanceof String) {String v = (String)value;System.out.println("遇到一个String类型" + v.toUpperCase());} else if (value instanceof Integer) {Integer v = (Integer)value;System.out.println("遇到一个整型类型" + v.longValue());}
}
新的写法
/*** 转换并申请了一个新的变量,极大地方便了代码的编写** @param value*/
public void matchByJDK17(Object value) {if (value instanceof String v) {System.out.println("遇到一个String类型" + v.toUpperCase());} else if (value instanceof Integer v) {System.out.println("遇到一个整型类型" + v.longValue());}
}
7. 集合类的工厂方法
推荐指数:⭐️⭐️⭐️⭐️⭐️
在Java8的年代,即便创建一个很小的集合,或者 固定元素 的集合都是比较麻烦的。
原来的写法
Set<String> set = new HashSet<>();
set.add("a");
set.add("b");
set.add("c"
新的写法
Set<String> set = Set.of("a", "b", "c");
二、其他的新特性
1. 新的String方法
- repeat:重复生成字符串
- isBlank:不用在引入第三方库就可以实现字符串判空了
- strip:去除字符串两边的空格,支持全角和半角,之前的trim只支持半角
- lines:能根据一段字符串中的终止符提取出行为单位的流
- indent:给字符串做缩进,接受一个int型的输入
- transform:接受一个转换函数,实现字符串的转换
2. Stream API的增强
增加takeWhile, dropWhile, ofNullable, iterate以及toList的API,越来越像一些函数式语言了。用法举例如下。
// takeWhile 顺序返回符合条件的值,直到条件不符合时即终止继续判断,
// 此外toList方法的加入,也大大减少了节省了代码量,免去了调用collect(Collectors::toList)方法了
List<Integer> list = Stream.of(2,2,3,4,5,6,7,8,9,10).takeWhile(i->(i%2==0)).toList(); // 返回2, 2// dropWhile 顺序去掉符合条件的值,直到条件不符合时即终止继续判断
List<Integer> list1 = Stream.of(2,2,3,4,5,6,7,8,9,10).dropWhile(i->(i%2==0)).toList(); //返回3, 4, 5, 6, 7, 8, 9, 10// ofNullable,支持传入空流,若没有这个且传入一个空流,那么将会抛NPE
var nullStreamCount = Stream.ofNullable(null).count(); //返回0// 以下两行都将输出0到9
Stream.iterate(0, n -> n < 10, n -> n + 1).forEach(x -> System.out.println(x));
Stream.iterate(0, n -> n + 1).limit(10).forEach(x -> System.out.println(x));
3. 全新的HttpClient
这个API首次出现在9之中,不过当时并非是一个稳定版本,
在Java11中正式得到发布,所以在Java17里面可以放心地进行使用。
原来的JDK自带的Http客户端真的非常难用,这也就给了很多像okhttp、restTemplate、Apache的HttpClient和feign这样的第三方库极大的发挥空间,几乎就没有人愿意去用原生的Http客户端的。
但现在不一样了,感觉像是 新时代的API了。FluentAPI风格,处处充满了现代风格,用起来也非常地方便,再也不用去依赖第三方的包了,好用。
// 同步请求
HttpClient client = HttpClient.newBuilder().version(Version.HTTP_1_1).followRedirects(Redirect.NORMAL).connectTimeout(Duration.ofSeconds(20)).proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 80))).authenticator(Authenticator.getDefault()).build();HttpResponse<String> response = client.send(request, BodyHandlers.ofString());System.out.println(response.statusCode());System.out.println(response.body()); // 异步请求
HttpRequest request = HttpRequest.newBuilder().uri(URI.create("https://foo.com/")).timeout(Duration.ofMinutes(2)).header("Content-Type", "application/json").POST(BodyPublishers.ofFile(Paths.get("file.json"))).build();client.sendAsync(request, BodyHandlers.ofString()).thenApply(HttpResponse::body).thenAccept(System.out::println);
4. JShell
在新的JDK版本中,支持直接在命令行下执行java程序,类似于python的交互式REPL。
简而言之,使用 JShell,你可以输入代码片段并马上看到运行结果,然后就可以根据需要作出调整,这样在验证一些简单的代码的时候,就可以通过jshell得到快速地验证,非常方便。
5. java命令 直接执行
java文件
在现在可以直接通过执行“java xxx.java”,即可运行该java文件,无须先执行javac,然后再执行java,是不是又简单了一步。
6. ZGC
在ParallelOldGC、CMS和G1之后,JDK 11引入了全新的ZGC(Z Garbage Collector)。这个名字本身就显得很牛。官方宣称ZGC的 垃圾回收 停顿时间不超过10ms,能支持高达16TB的堆空间,并且停顿时间不会随着堆的增大而增加。
.
那么,ZGC到底解决了什么问题?
Oracle官方介绍它是一个可伸缩的低延迟垃圾回收器,旨在降低停顿时间,尽管这可能会导致吞吐量的降低。
不过,通过横向扩展服务器可以解决吞吐量问题。官方已建议ZGC可用于生产环境,这无疑将成为未来的主流垃圾回收器。
小结:
随着Java8即将停止免费官方支持,越来越多的项目将转向Java17,包括大名鼎鼎的Spring Boot 3.0,它在2022年1月20日发布的第一个里程碑版本(M1)正是基于Java17构建的。
大多数情况下,从 JDK 8 升级到 JDK 17 是可行的,但需要对应用程序进行适当的测试和调整,以确保其在新版本上的稳定运行。
但是如果项目中其他成员使用了某些新特性,在Java8下将无法通过编译.,到时候再换就有点晚了
三、各版本 收费情况
JDK4 系列
Java 4.2.30 以后的所有版本
JDK5系列
Java 5.0.22 以后的所有版本
JDK6系列
Java 6.0.45以后的所有版本
JDK7系列
Java 7.0.80以后的所有版本
JDK8系列
Java 8.0.202以后的所有版本
JDK11~16系列
Java 11~16的所有版本
JDK17系列
Java 17 – 2024年12月以后所发布的所有版本
JDK21系列
预计到2027年JDK21也开始收费
相关文章:
JDK17 你的下一个白月光
JDK版本升级的非常快,现在已经到JDK20了。JDK版本虽多,但应用最广泛的还得是JDK8,正所谓“他发任他发,我用Java8”。 但实际情况却不是这样,越来越多的java工程师拥抱 JDK17,于是了解了一下 JDK17新语法&a…...
springboot优雅shutdown时如何保障异步线程的安全
我前面写了一篇springboot优雅shutdown的文章,看起来一切很美好。 https://blog.csdn.net/chenshm/article/details/139640775 那是因为没有进行多线程测试。如果一个请求中包括阻塞线程(主线程)和非阻塞线程(异步线程)…...
C++格式化库fmt使用方法
1. 格式化库fmt简介 fmt github地址 api说明 格式化参数说明 内容的格式化,体现在代码中主要表现为字符串、基本类型、自定义类型的拼接。例如说打印日志、拼接变量等。C中我们会经常使用类似printf,snprintf(C风格使用不方便),std::string.append(繁琐), std::io…...
HTML 颜色名:网页设计的调色板
HTML 颜色名:网页设计的调色板 在网页设计和开发中,颜色是一个关键元素,它不仅影响视觉效果,还能传达情感和品牌信息。HTML 颜色名是用于在 HTML 和 CSS 代码中指定颜色的预定义名称。这些颜色名易于记忆,方便设计师和开发者快速选择和应用颜色。本文将详细介绍 HTML 颜色…...
12306 火车票价格解析 (PHP 解析)
1. 从接口拿数据 日期 出发站 终点站 都填上 xxx/otn/leftTicketPrice/queryAllPublicPrice?leftTicketDTO.train_date2024-06-15&leftTicketDTO.from_stationBJP&leftTicketDTO.to_stationSJP&purpose_codesADULT 返回的数据是这样的 {"validateMess…...
了解统计学中不同类型的分布
目录 一、说明 二、均匀分布: 三、机器学习和数据科学中的均匀分布示例: 3.1 对数正态分布: 3.2 机器学习和数据科学中的对数正态分布示例: 四、 帕累托分布 4.1 什么是幂律? 4.2 机器学习和数据科学中的帕累托分布示例…...
k8s-CCE创建工作负载变量引用
CCE创建工作负载变量引用 背景,看到cce创建负载时会生成变量,如下。在skywaking-agent的使用,想要调用cce负载变量生成service_name。 -Dskywalking.agent.authentication里含有敏感信息需要写到配置项。简单粗糙的都写到配置项好像不合适。…...
后端主流框架--Spring02
前言:上篇关于Spring的文章介绍了一些Spring的基本知识,此篇文章主要分享一下如何配置Spring环境,如何注入等。 Spring项目构建 导入Spring相关JAR包 <dependency><groupId>org.springframework</groupId><artifactId>spring…...
[数据集][目标检测]减速带检测数据集VOC+YOLO格式5400张1类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):5400 标注数量(xml文件个数):5400 标注数量(txt文件个数):5400 标注…...
分析Linux操作指令及使用场景与频率分析 持续更新
本篇主要针对在日常工作与学习中使用较多的linux指令的使用方法以及使用频次进行分析与讲解,旨在能够更好的掌握这些必备的技能。 linux指令非常的多,如果要记住所有的指令使用方法是非常困难的且要花费很长的时间,很多人习惯离开使用去通篇…...
Redis 字符串(String)
Redis 字符串(String) 介绍 Redis是一种开源的、高性能的键值数据库,它支持多种类型的数据结构,其中字符串(String)是Redis中最基本的数据类型之一。字符串类型可以存储任何形式的字符串,包括文本、序列化的对象或二进制数据。在Redis中,字符串类型的最大容量为512MB。 …...
第一篇:容器化的未来:从Docker的革命到云原生架构
容器化的未来:从Docker的革命到云原生架构 1. 引言 在当今快速演进的技术领域,容器化技术已经成为云计算和微服务架构的重要组成部分。该技术以其高效的资源利用率、快速的部署能力和卓越的隔离性能,彻底改变了软件开发和部署的方式。容器化…...
【2024最新华为OD-C/D卷试题汇总】[支持在线评测] URL拼接(100分) - 三语言AC题解(Python/Java/Cpp)
🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 📎在线评测链接 URL拼接(100分) 🌍 评测功能需要订阅专栏后私信联系清隆解…...
反射,枚举以及lambda表达式
【本节目标】 1. 掌握反射 2. 掌握枚举 3. 掌握lambda表达式使用 反射 1 定义 Java的反射(reflection)机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调…...
DNS域名解析----分离解析、多域名解析、父域与子域
1 理论部分 1.1 分离解析 DNS的分离解析,是指根据不同的客户端提供不同的域名解析记录。来自不同地址的客户机请求解析同一域名时,为其提供不同的解析结果。也就是内外网客户请求访问相同的域名时,能解析出不同的IP地址,实现负载…...
Spring底层架构核心概念解析
BeanDefinition BeanDefinition表示Bean定义,BeanDefinition中存在很多属性用来描述一个Bean的特点.比如: beanClass:表示Bean类型scope:表示Bean作用域,单例/原型等lazyInit:表示Bean是否懒加载initMethodName:表示Bean初始化时要执行的方法destoryMethodName:表示Bean销毁时…...
C++ 44 之 指针运算符的重载
#include <iostream> #include <string> using namespace std;class Students04{ public:int m_age;Students04(int age){this->m_age age;}void showAge(){cout << "年龄是: " << this->m_age << endl;}~Students0…...
onlyoffice在线预览加载优化
背景: 使用容器部署onlyoffice到linux服务器,使用内网访问速度还可以接受,但是如果放到外网路径访问起来,速度就会很慢,甚至加载失败; 优化方案: 预览的过程排除网络因素,可以发现打…...
依赖自动装配
黑马程序员SSM框架 文章目录 1、依赖自动装配2、依赖自动装配的特征 1、依赖自动装配 IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配自动装配方式 按类型(常用)按名称按构造方法不启用自动装配 配置中使用bean标签auto…...
mysql和redis的双写一致性问题
一,使用方案 在使用redis作为缓存的场景下,我们一般使用流程如下 二,更新数据场景 我们此时修改个某条数据,如何保证mysql数据库和redis缓存中的数据一致呢? 按照常规思路有四种办法,1.先更新mysql数据&a…...
Qwen2——阿里巴巴最新的多语言模型挑战 Llama 3 等 SOTA
引言 经过几个月的期待, 阿里巴巴 Qwen 团队终于发布了 Qwen2 – 他们强大的语言模型系列的下一代发展。 Qwen2 代表了一次重大飞跃,拥有尖端的进步,有可能将其定位为 Meta 著名的最佳替代品 骆驼3 模型。在本次技术深入探讨中,我…...
等级考试3-2021年3月题
作业: #include <iostream> using namespace std; int chonghe(int,int,int,int); int main(){int a[1000],b[1000];int n,ma0;cin>>n;for(int i0;i<n;i){cin>>a[i]>>b[i];}for(int i0;i<n;i){for(int ji1;j<n;j){mamax(ma,chongh…...
Web前端开发PPT:深入探索与实战应用
Web前端开发PPT:深入探索与实战应用 在数字化时代,Web前端开发已成为构建丰富、交互性强的网页应用的关键环节。本次分享旨在通过PPT的形式,带领大家深入探索Web前端开发的精髓,并分享一些实战应用的经验。接下来,我们…...
liunx常见指令
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 二、安装环境 1.租借服务器 2.下载安装 XShell 3.使用xshll登录服务器 三、Linux基础命令 一、文件和命令 编辑1、cd 命令 2、pwd 命令 3、ls 命令 4、cp 命令 …...
vscode设置成中文界面
在Visual Studio Code(VSCode)中设置中文界面,你可以采用以下几种方法,以下是详细步骤: 方法一:通过设置菜单设置中文 打开VSCode:首先,确保你已经打开了VSCode软件。进入设置&…...
python命名空间详解
Python中的命名空间是编程语言设计的一个核心概念,它负责存储变量名与其对应的值之间的映射关系,确保了程序中变量的唯一性和可访问性。命名空间不仅关乎变量的生命周期和作用范围,也是Python中实现封装、避免命名冲突的重要机制。 1. 命名空…...
【日常记录】【vue】vite-plugin-inspect 插件的使用
文章目录 1、vite-plugin-inspect2、安装3、使用4、链接 1、vite-plugin-inspect vite-plugin-inspect 可以让开发者在浏览器端就可以看到vue文件编译后的代码、vue文件的相互依赖关系 2、安装 npm i -D vite-plugin-inspect// vite.config.ts import Inspect from vite-plugi…...
mini web框架示例
web框架: 使用web框架专门负责处理用户的动态资源请求,这个web框架其实就是一个为web服务器提供服务的应用程序 什么是路由? 路由就是请求的url到处理函数的映射,也就是说提前把请求的URL和处理函数关联好 管理路由可以使用一个…...
基于C#开发web网页管理系统模板流程-主界面统计功能完善
点击返回目录-> 基于C#开发web网页管理系统模板流程-总集篇-CSDN博客 前言 紧接上篇->基于C#开发web网页管理系统模板流程-主界面管理员入库和出库功能完善_c#web程序设计-CSDN博客 统计功能是管理系统很常见的功能,例如仓库管理系统要统计某时间段的出入库以…...
chromedriver114以后版本下载地址汇总chromedriver所有版本下载地址汇总国内源下载
谷歌浏览器版本经常会升级,chromedriver 也得下载匹配的版本 chromedriver 114以前版本下载地址https://registry.npmmirror.com/binary.html?pathchromedriver/ 但是自从115版本及其以后网站就找不到了,因此整理了截止2024年6月16日前所有在windows x6…...
网站聊天怎么做/百度知道
软件简介ECharts-X是 ECharts 团队推出的全新 3D 可视化库,它是基于ECharts 的扩展,底层深度整合了 WebGL 库QTEK和 Canvas2D库ZRender。特色混搭ECharts 里的混搭功能很强大,作为 ECharts 的扩展,ECharts-X 自然也需要支持。ECha…...
有用模板网在线制作免费网站/杭州seo搜索引擎优化公司
前言 千万级大表如何优化,这是一个很有技术含量的问题,通常我们的直觉思维都会跳转到拆分或者数据分区。除此之外,还有其他的思路和解决方案。根据本人多年的工作经验,做了如下总结。 方案 "千万级大表优化"这句话有…...
web个人网站设计毕业论文/深圳网络营销
sorted(iterable, *, keyNone, reverseFalse) 根据 iterable 中的项返回一个新的已排序列表。具有两个可选参数,它们都必须指定为关键字参数。key 指定带有单个参数的函数,用于从 iterable 的每个元素中提取用于比较的键 (例如 keystr.lower)。 默认值为…...
wordpress 评论表情插件/aso应用优化
前言 本章内容是android.os.HandlerThread,版本为Android 3.1 r1,翻译来自"雪鹰工作室",再次感谢"雪鹰工作室"!欢迎你一起参与Android的中文翻译,联系我over140gmail.com。 声明 欢迎转载&#x…...
做网站有生意吗/seo还能赚钱吗
1、目标今天的目标是某生鲜App的签名 paramsMD5 ,抓个包先:javaTIP: 新鲜热乎的 1.4.5python2、步骤老规矩,上jadx纳尼...... 这个 qihoo 很眼熟,在Windows平台下是老熟人了,没想到如今混移动端了,它又冒出…...
wordpress如何上传源码/首页优化排名
图片填充整个PictureBox 只需要设置属性 pictureBox.SizeMode PictureBoxSizeMode.StretchImage;转载于:https://www.cnblogs.com/wuhuisheng/archive/2012/04/06/2434394.html...