【微软技术栈】C#.NET 泛型数学
本文内.NET 7 为基类库引入了新的数学相关泛型接口。 提供这些接口意味着可以将泛型类型或方法的类型参数约束为“类似于数字”。 此外,C# 11 及更高版本允许定义 static virtual 接口成员。 由于必须将运算符声明为 static,因此这一新的 C# 功能可用于在新接口中为类似于数字的类型声明运算符。
总之,这些创新使你可以常规地执行数学运算,也就是说,无需知道正在使用的确切类型。 例如,如果想编写一个将两个数字相加的方法,在以前,必须为每种类型添加方法的重载(例如,static int Add(int first, int second) 和 static float Add(float first, float second))。 现在,可以编写一个单一的泛型方法,其中将类型参数约束为类似于数字的类型。 例如:
static T Add<T>(T left, T right)where T : INumber<T>
{return left + right;
}
在此方法中,类型参数 T 约束为了实现新 INumber<TSelf> 接口的类型。 INumber<TSelf> 实现了 IAdditionOperators<TSelf,TOther,TResult> 接口,其中包含 + 运算符。 这使得该方法可以常规地将两个数字相加。 该方法可以与 .NET 的任何内置数字类型一起使用,因为它们都已更新为在 .NET 7 中实现 INumber<TSelf>。
库作者将从泛型数学接口中受益最多,因为他们可以通过删除“冗余”重载来简化其代码库。 其他开发人员将间接受益,因为他们使用的 API 可能会开始支持更多类型。
1、接口
接口设计为既需要足够细化(以便用户可以在上面定义自己的接口),又要足够精细(以便易于使用)。 在这种情况下,大多数用户会与一些核心数字接口进行交互,例如 INumber<TSelf> 和 IBinaryInteger<TSelf>。 更细化的接口(例如 IAdditionOperators<TSelf,TOther,TResult> 和 ITrigonometricFunctions<TSelf>)支持这些类型,并且可供开发人员使用,定义其自己的特定于域的数字接口。
- 数字接口
- 运算符接口
- 函数接口
- 分析和格式化接口
1.1 数字接口
本部分介绍 System.Numerics 中的接口,这些接口描述了类似于数字的类型及其可用的功能。
| 接口名称 | 说明 |
|---|---|
| IBinaryFloatingPointIeee754<TSelf> | 公开对实现 IEEE 754 标准的二进制浮点类型1通用的 API。 |
| IBinaryInteger<TSelf> | 公开对二进制整数通用的 API2。 |
| IBinaryNumber<TSelf> | 公开对二进制数字通用的 API。 |
| IFloatingPoint<TSelf> | 公开对浮点类型通用的 API。 |
| IFloatingPointIeee754<TSelf> | 公开对实现 IEEE 754 标准的浮点类型通用的 API。 |
| INumber<TSelf> | 公开对可比较数字类型(实际上是“实数”数字域)通用的 API。 |
| INumberBase<TSelf> | 公开对所有数字类型(实际上是“复数”数字域)通用的 API。 |
| ISignedNumber<TSelf> | 公开对所有有符号数字类型通用的 API(例如 NegativeOne 的概念)。 |
| IUnsignedNumber<TSelf> | 公开对所有无符号数字类型通用的 API。 |
| IAdditiveIdentity<TSelf,TResult> | 公开 (x + T.AdditiveIdentity) == x 的概念。 |
| IMinMaxValue<TSelf> | 公开 T.MinValue 和 T.MaxValue 的概念。 |
| IMultiplicativeIdentity<TSelf,TResult> | 公开 (x * T.MultiplicativeIdentity) == x 的概念。 |
1二进制浮点类型是 Double (double)、Half 和 Single (float)。
2二进制整数类型是 Byte (byte)、Int16 (short)、Int32 (int)、Int64 (long)、Int128、IntPtr (nint)、SByte (sbyte)、UInt16 (ushort)、UInt32 (uint)、UInt64 (ulong)、UInt128 和 UIntPtr (nuint)。
最有可能直接使用的接口是 INumber<TSelf>,它大致对应于一个实数。 如果某个类型实现了此接口,则意味着一个值有一个符号(这包括 unsigned 类型,这些类型被认为是正数)并且可以与相同类型的其他值进行比较。 INumberBase<TSelf> 提供复数和虚数等更高级的概念,例如负数的平方根。 创建其他接口(例如 IFloatingPointIeee754<TSelf>)是因为并非所有操作都对所有数字类型都有意义。例如,计算数字的下限仅对浮点类型有意义。 在 .NET 基类库中,浮点类型 Double 实现 IFloatingPointIeee754<TSelf>,但 Int32 不实现。
一些接口也由各种其他类型实现,包括 Char、DateOnly、DateTime、DateTimeOffset、Decimal、Guid、TimeOnly 和 TimeSpan。
下表显示了每个接口公开的一些核心 API。
| 接口 | API 名称 | 说明 |
|---|---|---|
| IBinaryInteger<TSelf> | DivRem | 同时计算商和余数。 |
LeadingZeroCount | 计算二进制表示中的前导零位数。 | |
PopCount | 计算二进制表示中的设置位数。 | |
RotateLeft | 向左旋转位,有时也称为循环左移。 | |
RotateRight | 向右旋转位,有时也称为循环右移。 | |
TrailingZeroCount | 计算二进制表示中的尾随零位数。 | |
| IFloatingPoint<TSelf> | Ceiling | 将值向正无穷方向舍入。 +4.5 变为 +5,-4.5 变为 -4。 |
Floor | 将值向负无穷方向舍入。 +4.5 变为 +4,-4.5 变为 -5。 | |
Round | 使用指定的舍入模式对值进行舍入。 | |
Truncate | 将值向零舍入。 +4.5 变为 +4,-4.5 变为 -4。 | |
| IFloatingPointIeee754<TSelf> | E | 获取一个值,该值表示该类型的欧拉数。 |
Epsilon | 获取该类型的大于零的最小可表示值。 | |
NaN | 获取表示类型 NaN 的值。 | |
NegativeInfinity | 获取表示类型 -Infinity 的值。 | |
NegativeZero | 获取表示类型 -Zero 的值。 | |
Pi | 获取表示类型 Pi 的值。 | |
PositiveInfinity | 获取表示类型 +Infinity 的值。 | |
Tau | 获取表示类型 Tau (2 * Pi) 的值。 | |
| (其他) | (实现函数接口下列出的全部接口。) | |
| INumber<TSelf> | Clamp | 将值限制为不大于也不小于指定的最小值和最大值。 |
CopySign | 将指定值的符号设置为与另一个指定值相同。 | |
Max | 返回两个值中的较大值,如果任一输入为 NaN,则返回 NaN。 | |
MaxNumber | 返回两个值中的较大值,如果一个输入为 NaN,则返回数字。 | |
Min | 返回两个值中的较小值,如果任一输入为 NaN,则返回 NaN。 | |
MinNumber | 返回两个值中的较小值,如果一个输入为 NaN,则返回数字。 | |
Sign | 返回 -1 表示负值,0 表示零,+1 表示正值。 | |
| INumberBase<TSelf> | One | 获取类型的值 1。 |
Radix | 获取类型的基数。 Int32 返回 2。 Decimal 返回 10。 | |
Zero | 获取类型的值 0。 | |
CreateChecked | 创建一个值,如果输入不合适,则引发 OverflowException。1 | |
CreateSaturating | 创建一个值,如果输入不合适,则钳制为 T.MinValue 或 T.MaxValue。1 | |
CreateTruncating | 从一个值创建另一个值,如果输入不适合,则环绕处理。1 | |
IsComplexNumber | 如果值具有非零实部和非零虚部,则返回 true。 | |
IsEvenInteger | 如果值为偶数整数,则返回 true。 2.0 返回 true,2.2 返回 false。 | |
IsFinite | 如果值不是无限值且不是 NaN,则返回 true。 | |
IsImaginaryNumber | 如果值的实部为零,则返回 true。 这意味着 0 是虚构的,而 1 + 1i 不是。 | |
IsInfinity | 如果值表示无穷大,则返回 true。 | |
IsInteger | 如果值为整数,则返回 true。 2.0 和 3.0 返回 true,2.2 和 3.1 返回 false。 | |
IsNaN | 如果值表示 NaN,则返回 true。 | |
IsNegative | 如果值为负,则返回 true。 这包括 -0.0。 | |
IsPositive | 如果值为正,则返回 true。 这包括 0 和 +0.0。 | |
IsRealNumber | 如果值的虚部为零,则返回 true。 这意味着 0 是实数,所有 INumber<T> 类型也是如此。 | |
IsZero | 如果值表示零,则返回 true。 这包括 0、+0.0 和 -0.0。 | |
MaxMagnitude | 返回绝对值较大的值,如果任一输入为 NaN,则返回 NaN。 | |
MaxMagnitudeNumber | 返回绝对值较小的值,如果一个输入为 NaN,则返回数字。 | |
MinMagnitude | 返回绝对值较小的值,如果任一输入为 NaN,则返回 NaN。 | |
MinMagnitudeNumber | 返回绝对值较小的值,如果一个输入为 NaN,则返回数字。 | |
| ISignedNumber<TSelf> | NegativeOne | 获取类型的值 -1。 |
1为帮助理解三种 Create* 方法的行为,请考虑以下示例。
给定值过大时的示例:
byte.CreateChecked(384)将引发 OverflowException。byte.CreateSaturating(384)返回 255,因为 384 大于 Byte.MaxValue(即 255)。byte.CreateTruncating(384)返回 128,因为采用最低 8 位(384 的十六进制表示为0x0180,最低 8 位为0x80,即 128)。
给定值过小时的示例:
byte.CreateChecked(-384)将引发 OverflowException。byte.CreateSaturating(-384)返回 0,因为 -384 小于 Byte.MinValue(即 0)。byte.CreateTruncating(-384)返回 128,因为采用最低 8 位(384 的十六进制表示为0xFE80,最低 8 位为0x80,即 128)。
Create* 方法对 IEEE 754 浮点类型也有一些特殊考虑,例如 float 和 double,因为它们具有特殊值 PositiveInfinity、NegativeInfinity 和 NaN。 所有三个 Create* API 都表现为 CreateSaturating。 此外,虽然 MinValue 和 MaxValue 表示最大的负/正“正常”数,但实际的最小值和最大值是 NegativeInfinity 和 PositiveInfinity,因此它们改为钳制这些值。
1.2 运算符接口
运算符接口对应于可用于 C# 语言的各种运算符。
- 它们明确地不对乘法和除法等操作进行配对,因为这并非对所有类型都正确。 例如,
Matrix4x4 * Matrix4x4有效,但Matrix4x4 / Matrix4x4无效。 - 它们通常允许输入类型和结果类型不同,以支持诸如将两个整数相除以获取
double(例如3 / 2 = 1.5)或计算一组整数的平均值等方案。
| 接口名称 | 定义的运算符 |
|---|---|
| IAdditionOperators<TSelf,TOther,TResult> | x + y |
| IBitwiseOperators<TSelf,TOther,TResult> | x & y、x | y、x ^ y 和 ~x |
| IComparisonOperators<TSelf,TOther,TResult> | x < y、x > y、x <= y 和 x >= y |
| IDecrementOperators<TSelf> | --x 和 x-- |
| IDivisionOperators<TSelf,TOther,TResult> | x / y |
| IEqualityOperators<TSelf,TOther,TResult> | x == y 和 x != y |
| IIncrementOperators<TSelf> | ++x 和 x++ |
| IModulusOperators<TSelf,TOther,TResult> | x % y |
| IMultiplyOperators<TSelf,TOther,TResult> | x * y |
| IShiftOperators<TSelf,TOther,TResult> | x << y 和 x >> y |
| ISubtractionOperators<TSelf,TOther,TResult> | x - y |
| IUnaryNegationOperators<TSelf,TResult> | -x |
| IUnaryPlusOperators<TSelf,TResult> | +x |
备注
除了常规的 unchecked 运算符之外,一些接口还定义了 checked 运算符。 Checked 运算符在 checked 上下文中调用,并允许用户定义的类型定义溢出行为。 如果实现了 checked 运算符,例如 CheckedSubtraction(TSelf, TOther),则还必须实现 unchecked 的运算符,例如 Subtraction(TSelf, TOther)。
1.3 函数接口
函数接口定义了比特定数值接口更广泛应用的泛型数学 API。 这些接口都由 IFloatingPointIeee754<TSelf> 实现,未来可能会由其他相关类型实现。
| 接口名称 | 说明 |
|---|---|
| IExponentialFunctions<TSelf> | 公开支持 e^x、e^x - 1、2^x、2^x - 1、10^x 和 10^x - 1 的指数函数。 |
| IHyperbolicFunctions<TSelf> | 公开支持 acosh(x)、asinh(x)、atanh(x)、cosh(x)、sinh(x) 和 tanh(x) 的双曲线函数。 |
| ILogarithmicFunctions<TSelf> | 公开支持 ln(x)、ln(x + 1)、log2(x)、log2(x + 1)、log10(x) 和 log10(x + 1) 的对数函数。 |
| IPowerFunctions<TSelf> | 公开支持 x^y 的幂函数。 |
| IRootFunctions<TSelf> | 公开支持 cbrt(x) 和 sqrt(x) 的根函数。 |
| ITrigonometricFunctions<TSelf> | 公开支持 acos(x)、asin(x)、atan(x)、cos(x)、sin(x) 和 tan(x) 的三角函数。 |
1.4 解析和格式化接口
解析和格式化是编程中的核心概念。 它们通常在将用户输入转换为给定类型或向用户显示类型时使用。 这些接口位于 System 命名空间中。
| 接口名称 | 说明 |
|---|---|
| IParsable<TSelf> | 公开对 T.Parse(string, IFormatProvider) 和 T.TryParse(string, IFormatProvider, out TSelf) 的支持。 |
| ISpanParsable<TSelf> | 公开对 T.Parse(ReadOnlySpan<char>, IFormatProvider) 和 T.TryParse(ReadOnlySpan<char>, IFormatProvider, out TSelf) 的支持。 |
| IFormattable1 | 公开对 value.ToString(string, IFormatProvider) 的支持。 |
| ISpanFormattable1 | 公开对 value.TryFormat(Span<char>, out int, ReadOnlySpan<char>, IFormatProvider) 的支持。 |
1此接口不是新接口,也不是泛型接口。 但是,它由所有数字类型实现,表示 IParsable 的逆运算。
例如,以下程序将两个数字作为输入,使用类型参数限制为 IParsable<TSelf> 的泛型方法从控制台读取它们。 该程序使用泛型方法计算平均值,其中将输入和结果值的类型参数约束为 INumber<TSelf>,然后将结果显示到控制台。
相关文章:
【微软技术栈】C#.NET 泛型数学
本文内.NET 7 为基类库引入了新的数学相关泛型接口。 提供这些接口意味着可以将泛型类型或方法的类型参数约束为“类似于数字”。 此外,C# 11 及更高版本允许定义 static virtual 接口成员。 由于必须将运算符声明为 static,因此这一新的 C# 功能可用于在…...
【nlp】1.1文本处理的基本方法
文本处理的基本方法 1 什么是分词2 什么是命名实体识别3 什么是词性标准1 什么是分词 分词就是将连续的字序列按照一定的规范重新组合成词序列的过程。在英文的行文中,单词之间是以空格作为自然分界符的,而中文只是字、句和段能通过明显的分界符来简单划界,唯独词没有一个形…...
流量分析(信息安全铁人三项赛分区赛2-5.18)
题目描述 目录 题目描述 黑客的IP是多少 服务器1.99的web服务器使用的CMS及其版本号(请直接复制) 服务器拿到的webshell的网址(请输入url解码后的网址) 服务器1.99的主机名 网站根目录的绝对路径(注意最后加斜杠) 黑客上传的第一个文件名称是什么 黑客进行内网扫描&am…...
云服务器如何选?腾讯云2核2G3M云服务器88元一年!
作为一名程序员,在选择云服务器时,我们需要关注几个要点:网络稳定性、价格以及云服务商的规模。这些要素将直接影响到我们的使用体验和成本效益。接下来,我将为大家推荐一款性价比较高的轻应用云服务器。 腾讯云双11活动 腾讯云…...
【Hello Go】初识Go语言
初识Go语言 Go语言介绍Go语言是什么Go语言优势Go语言能用来做什么 Go语言环境安装第一个GO语言程序运行Go语言程序 Go语言介绍 Go语言是什么 go语言是是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言. 静态类型:在静态类型…...
计算机视觉:人脸识别与检测
目录 前言 识别检测方法 本文方法 项目解析 完整代码及效果展示 前言 人脸识别作为一种生物特征识别技术,具有非侵扰性、非接触性、友好性和便捷性等优点。人脸识别通用的流程主要包括人脸检测、人脸裁剪、人脸校正、特征提取和人脸识别。人脸检测是从获取的图…...
【NLP】理解 Llama2:KV 缓存、分组查询注意力、旋转嵌入等
LLaMA 2.0是 Meta AI 的开创性作品,作为首批高性能开源预训练语言模型之一闯入了 AI 场景。值得注意的是,LLaMA-13B 的性能优于巨大的 GPT-3(175B),尽管其尺寸只是其一小部分。您无疑听说过 LLaMA 令人印象深刻的性能,但您是否想知…...
ctyunos 与 openeuler
ctyunos-2.0.1-220311-aarch64-dvd ctyunos-2.0.1-220329-everything-aarch64-dvd glibc python3 对应openEuler 20.03 LTS SP1...
跟着GPT学设计模式之工厂模式
工厂模式(Factory Design Pattern)分为三种更加细分的类型:简单工厂、工厂方法和抽象工厂。在这三种细分的工厂模式中,简单工厂、工厂方法原理比较简单,在实际的项目中也比较常用。而抽象工厂的原理稍微复杂点…...
VScode+python开发,多个解释器切换问题
内容:主要VScode使用多个解释器 环境准备 VScode编辑器,两个版本python解释器 python3.7.2 python3.11.6 问题: 目前我们的电脑安装了python3.7.2、python3.11.6两个解释器,在vscode编辑器中,无法切换解释器使用如…...
c++ 经典服务器开源项目Tinywebserver如何运行
第一次直接按作者的指示,运行sh ./build.sh,再运行./server,发现不起作用,localhost:9006也是拒绝访问的状态,后来摸索成功了发现,运行./server之后,应该是启动状态,就是不会退出,而…...
c++之xml的创建,增删改查
c之xml的创建,增删改查 1.创建写入2.添加3.删除4.修改: 1.创建写入 #include <stdio.h> #include <typeinfo> #include "F:/EDGE/tinyxml/tinyxml.h" #include <iostream> #include <string> #include <Winsock2.…...
【前端开发】JS Vue React中的通用递归函数
目录 前言 一、递归函数的由来 二、功能实现 1.后台数据 2.处理数据 3.整体代码 总结 🙂博主:冰海恋雨. 🙂文章核心:【前端开发】JS Vue React中的通用递归函数 前言 大家好,今天和大家分享一下在前端开发中j…...
【python 生成器 面试必备】yield关键字,协程必知必会系列文章--自己控制程序调度,体验做上帝的感觉 1
python生成器系列文章目录 第一章 yield — Python (Part I) 文章目录 python生成器系列文章目录前言1. Generator Function 生成器函数2.并发和并行,抢占式和协作式2.Let’s implement Producer/Consumer pattern using subroutine: 生成器的状态 generator’s st…...
头哥实践平台之MapReduce基础实战
一. 第1关:成绩统计 编程要求 使用MapReduce计算班级每个学生的最好成绩,输入文件路径为/user/test/input,请将计算后的结果输出到/user/test/output/目录下。 先写命令行,如下: 一行就是一个命令 touch file01 echo Hello World Bye Wor…...
Linux基础知识——tmux和vim
Linux基础知识——tmux和vim 文章目录 Linux基础知识——tmux和vim一、tmux1. 功能2. 结构3. 操作 二、vim功能模式操作 一、tmux tmux配置:~/.tmux.conf修改为如下 set-option -g status-keys vi setw -g mode-keys visetw -g monitor-activity on# setw -g c0-cha…...
Java Web——TomcatWeb服务器
目录 1. 服务器概述 1.1. 服务器硬件 1.2. 服务器软件 2. Web服务器 2.1. Tomcat服务器 2.2. 简单的Web服务器使用 1. 服务器概述 服务器指的是网络环境下为客户机提供某种服务的专用计算机,服务器安装有网络操作系统和各种服务器的应用系统服务器的具有高速…...
Zookeeper 命令使用和数据说明
文章目录 一、概述二、命令使用2.1 登录 ZooKeeper2.2 ls 命令,查看目录树(节点)2.3 create 命令,创建节点2.4 delete 命令,删除节点2.5 set 命令,设置节点数据2.6 get 命令,获取节点数据 三、数…...
索尼RSV文件怎么恢复为MP4视频
索尼相机RSV是什么文件? 如果您的相机是索尼SONY A7S3,A7M4,FX3,FX3,FX6,或FX9等,有时录像会产生一个RSV文件,而没有MP4视频文件。RSV其实是MP4的前期文件,经我对RSV文件…...
pytorch-gpu(Anaconda3+cuda+cudnn)
文章目录 下载Anaconda3安装,看着点next就行比较懒所以自动添加path测试 cuda安装的时候不能改路径如果出现报错,关闭杀毒软件一直下一步就好取消勾选“CUDA”中的“Visual Studio Intergration”一直下一步即可测试安装成功 cudnn解压后将这三个文件夹复…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 ` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
