精华内容
下载资源
问答
  • 2020-11-25 00:14:34

    华为存储特性

    1、SmartPartition

    SmartPartition是一种性能特性,根据不同业务特点分配存储系统的缓存资源来满足不同应用系统的服务质量要求。
    由于单个存储系统要面对的应用数量急剧增加,且各业务应用之间的I/O特征不同,导致业务应用之间相互争抢资源,关键业务应用的性能无法得到保障。由于缓存是存储系统和前端应用系统传输数据的必经之道,所以缓存分区是一种提高服务质量保证能力的重要方法。SmartPartion特性是华为公司研发的缓存分区特性,又称智能缓存分区特性。
    SmartPartition特性通过给不同级别的用户配置不同大小的缓存分区,系统将保证该分区所占用的缓存容量,从而保证位于该分区中的业务应用的服务性能。

    快照

    快照的实现方式包括COW(Copy On Write)和ROW(Redirect On Write)。

    COW即写时拷贝,受快照保护的数据要发生变化时,先将待修改的数据对象拷贝至另一个位置或对象,保存下来作为快照版本,再将修改的数据覆盖写入原数据对象中。

    ROW即重定向写,受快照保护的数据要发生变化时,将修改的数据写入新的位置或对象,不覆盖当前的数据。

    OceanStor 9000采用元数据COW和数据ROW的方式实现快照。

    HyperSnap

    华为技术有限公司开发的快照特性名称为HyperSnap。快照是指在不中断正常业务的前提下,生成源数据在某一时间点的一致性数据副本。
    在最初的数据备份方式中,恢复时间目标(RTO)和恢复点目标(RPO)无法满足业务的需求,而且数据备份过程会影响业务性能,甚至中断业务。当企业数据量逐渐增加且数据增长速度不断加快时,如何缩短备份窗口成为系统管理员重点关注的问题。因此,各种数据备份、数据保护技术应运而生。

    RTO(Recovery Time Objective):一种业务切换策略,是容灾切换时间最短的策略。以恢复时间点为目标,确保容灾机能够快速接管业务。
    RPO(Recovery Point Objective):一种业务切换策略,是数据丢失最少的容灾切换策略。以数据恢复点为目标,确保容灾切换所使用的数据为最新的备份数据。
    备份窗口:对数据进行备份而不严重影响使用该数据的应用程序时,进行数据备份的时间间隔。

    快照技术是众多数据备份技术中的一种,其原理与日常生活中的拍照类似,通过拍照可以快速记录下拍照时间点被拍照对象的状态。由于可以瞬间生成快照,通过快照技术,系统管理员能够实现零备份窗口的数据备份,从而满足企业对业务连续性和数据可靠性的要求。

    原理
    快照是源数据在某一时间点生成的数据副本,由源LUN、COW数据空间和快照LUN三部分组成。快照具有执行速度快、占用存储空间小等特点。

    (块业务)
    写前拷贝(COW,Copy-on-write)
    快照实现的核心技术,用于保存源LUN中变化的数据。快照创建并激活后,如果应用服务器对源LUN有写数据请求,存储系统首先将被写入位置的原数据(写前拷贝数据)拷贝到COW数据空间中,然后修改写前拷贝数据的映射关系,记录写前拷贝数据在COW数据空间中的新位置,最后再将新数据写入到源LUN中。
    (文件业务)
    ROW
    ROW(Redirect on write)是指写时重定向技术,是实现文件系统快照的核心技术。当源文件系统收到写数据请求需要修改源文件系统中的数据时,存储系统在存储池中为新写入的数据指定新的存储位置,并将被修改数据块的指针指向新的存储位置。

    HyperReplication

    华为i的远程复制特性又叫HyperReplication特性。远程复制为用户提供了灵活且强大的数据复制功能,通过远程复制能够实现数据的远端备份和恢复、持续的业务数据支撑、数据的容灾恢复。
    定义
    当存储系统运行块业务时,远程复制支持以下两种复制模式:

    同步远程复制
    实时地同步数据,最大限度保证数据的一致性,以减少灾难发生时的数据丢失量。

    异步远程复制
    周期性地同步数据,最大限度减少由于数据远程传输的时延而造成的业务性能下降。

    HyperClone(克隆)

    的克隆特性又叫HyperClone特性。块业务克隆特性能够在不中断主机业务的情况下实现LUN级别数据的完整备份,可用于数据备份与恢复、应用测试与数据分析等场景。
    背景
    在一些实际应用中,用户需要从生产数据中复制出一份副本用于独立的测试、分析,这种用途催生了能适配该需求的数据保护技术——克隆。包含LUN克隆和文件系统克隆两大功能,分别针对块业务和文件业务进行克隆。LUN克隆特性可以满足数据备份的要求。

    定义
    LUN克隆特性是快照技术的一种,是源数据在某个时间点的完整副本,是一种可增量同步的备份方式。其中:

    “完整”指对源数据进行完全复制生成数据副本。
    “增量同步”指数据副本可动态同步源数据的变更部分。
    本存储系统的LUN克隆特性中,保存源数据的LUN称为主LUN,保存数据副本的LUN称为从LUN。

    SmartTier

    SmartTier特性可以通过将用户数据进行分级存储,从而提高存储系统性能并降低用户成本。
    背景
    由于硬盘技术的进步,存储系统支持的存储介质类型和数量已显著增加。不同存储介质在存储成本和存储性能方面的差异很大,这导致用户难以在存储成本和存储性能之间权衡:

    SSD硬盘的响应时间很短,每单位存储请求处理成本很低,但每单位存储容量成本很高。
    NL-SAS硬盘每单位存储容量成本较低,但响应时间很长且每单位存储请求处理成本很高。
    SAS硬盘介于以上两者之间。
    定义
    华为技术有限公司开发的SmartTier特性又叫智能数据分级特性。SmartTier提供智能化数据存储管理的功能,通过统计和分析数据的活跃度,将不同活跃度的数据和不同特点的存储介质动态匹配。

    目的和受益
    SmartTier通过数据迁移将活跃度高的繁忙数据迁移至具有更高性能的存储介质(如SSD硬盘),将活跃度低的空闲数据迁移至具有更高容量且更低容量成本的存储介质(如NL-SAS硬盘),从而为繁忙数据提供更短的响应时间、更高的IOPS(Input/Output Operations Per Second),提高存储系统性能。

    SmartTier的统计、分析和迁移活动基于SmartTier的实现策略和数据的性能要求。在统计、分析、迁移活动期间,不会对现有业务连续性和数据可用性造成影响。

    SmartQoS

    SmartQoS特性可以满足某些应用程序的特定性能目标,提供强大的存储系统控制能力。
    SmartQoS特性又叫智能服务质量控制特性,可以通过动态地分配存储系统的资源来满足某些应用程序的特定性能目标。

    SmartQoS特性扩展了信息生命周期管理策略,在存储系统中实现了应用程序性能的分层。SmartQoS是对存储系统的一个极为重要的增强特性,尤其是在某些应用程序需要高服务级别的环境中。在同一台存储设备上部署多个应用程序时,通过合理配置SmartQoS特性,用户可以得到最大化整合的利益。

    SmartPartition

    的SmartPartition特性又叫智能缓存分区特性。SmartPartition特性是一种性能特性,通过给不同级别的用户配置不同大小的缓存分区,系统将保证该分区所占用的缓存容量,从而提升位于该分区中的业务应用的服务性能。
    SmartPartition特性对LUN(块业务)和文件系统(文件业务)均有效。

    SmartVirtualization

    通过SmartVirtualization特性,存储系统能够对异构存储系统中的存储资源进行接管并实现集中管理,结合SmartMigration特性还可以实现对异构存储系统中的数据进行在线迁移,迁移结束承载业务。
    SmartVirtualization特性又叫异构虚拟化特性,是指本端存储系统与异构存储系统相互连接后,本端存储系统能够将异构存储系统提供的存储资源当作本地存储资源进行使用并对其进行集中管理,无需关注存储系统间软件架构和硬件架构的差异。

    SmartVirtualization特性仅对LUN(块业务)有效。

    由于解决了不同存储系统之间的兼容性问题,用户可以集中管理本端存储系统及异构存储系统中的存储资源,同时用户仍然可以使用旧存储系统的存储资源,降低对原有投资的浪费。

    本端存储系统是指V5存储系统;异构存储系统包括华为存储系统(不包括OEM的华为存储系统)和第三方厂商的存储系统。
    使用SmartVirtualization特性只能管理异构存储系统上的存储资源,不能对异构存储系统进行配置操作。

    SmartMigration

    SmartMigration特性又称智能数据迁移特性,是业务迁移的关键技术,可以实现存储系统内和存储系统间的业务数据迁移。
    SmartMigration能够在不中断主机业务的情况下实现源LUN上的业务完整地迁移至目标LUN,并在迁移结束后使目标LUN完全替代源LUN并承载业务,而用户无感知。SmartMigration技术应运而生,它不仅实现了在不中断主机业务的情况下完成存储系统内部的业务数据迁移,还实现了华为存储系统和与其兼容的其他存储系统之间的业务数据迁移。

    SmartCache

    SmartCache特性又叫智能数据缓存特性。
    SmartCache特性能够提高存储系统中读热点数据的访问效率,可用于存在热点数据且以读操作为主的随机小I/O场景。
    由于SSD(Solid State Disk)盘响应时间短,且容量远大于普通缓存资源的容量,通过将SSD盘作为读缓存资源,可以减少存储系统的读响应时间,有效提高热点数据的访问效率。
    利用SSD盘对随机小I/O读取速度快的特点,将SSD盘组成智能缓存池,将访问频率高的随机小I/O读热点数据从传统的机械硬盘移动到由SSD盘组成的高速智能缓存池中。由于SSD盘的数据读取速度远远高于机械硬盘,所以SmartCache特性可以缩短热点数据的响应时间,从而提升系统的性能。

    SmartCache将智能缓存池划分成多个分区,为业务提供细粒度的SSD缓存资源,不同的业务可以共享同一个分区,也可以分别使用不同的分区,各个分区之间互不影响。从而向关键应用提供更多的缓存资源,保障关键应用的性能。

    应用SmartCache特性不会中断现有业务,也不会影响数据的可靠性。
    相关概念
    智能缓存池
    智能缓存池由SSD盘组成,可以作为普通缓存资源RAM(Random Access Memory) Cache的扩充,用于存储热点数据。

    SmartCache分区
    SmartCache特性将智能缓存池划分成多个分区,不同的业务可以共享同一个分区,也可以分别使用不同的分区,各个分区之间互不影响。从而向关键应用提供更多的缓存资源,保障关键应用的性能。

    SmartMulti-Tenant(多租户)

    多租户特性又称SmartMulti-Tenant。多租户特性通过在一套物理存储系统中创建多个虚拟存储系统,为多个租户提供了更加灵活、更易于管理、部署成本更低且不影响相互的数据安全性和隐私的共享存储资源。

    HyperMirror

    卷镜像特性又叫HyperMirror。卷镜像通过持续对LUN进行冗余备份保护,从而提高LUN的可靠性,降低容灾风险和运维成本。
    背景
    随着企业的高速发展,业务数据量不断攀升,数据已经成为企业的核心资产。很多现实情况下,已经对数据进行了很好的冗余备份保护,但不能保障当数据所在的存储空间故障时,数据业务不受任何影响的运行。所以在保障数据不丢失的前提下,保证数据业务不间断地运行成为了数据容灾备份的关键。

    卷镜像特性可以很好地解决以上问题,用户可以对数据所在的存储空间进行持续保护,并保障在存储空间故障时,主机侧的业务不间断地正常工作。

    定义
    卷镜像是一种数据持续保护技术,可以为一个LUN创建两个镜像物理副本,对LUN提供持续的冗余备份保护而主机侧不受任何影响。

    卷镜像特性的主要特点包括:

    对一个LUN提供两个镜像物理副本,这两个副本中的数据是完全一样的。当其中的一个镜像副本出现故障时,LUN上的业务不受任何影响,主机侧仍然可以毫无感知的正常工作。
    这个被持续保护的LUN可以是OceanStor系列存储系统(以下简称为本端存储系统)的LUN,也可以是第三方存储系统(以下简称异构存储系统)的LUN。这样不仅可以提高本端存储系统LUN可靠性,同样可以提高异构存储系统LUN的可靠性。
    可以对做卷镜像保护的LUN配置其他增值特性,对数据进行多重保护。

    SmartDedupe&SmartCompression

    SmartDedupe&SmartCompression特性通过减少数据占用的存储空间,提高存储系统的空间利用率,满足日益增长的数据存储需求。
    SmartDedupe&SmartCompression特性又叫智能数据重删压缩特性。
    SmartDedupe&SmartCompression特性包含重复数据删除和数据压缩两种特性。
    重复数据删除特性(SmartDedupe)是一种数据缩减技术,通过删除存储系统中的冗余数据块,减少数据占用的物理存储容量,从而满足日益增长的数据存储需求。OceanStor 存储系统支持的是在线重复数据删除,即只对新写入的数据进行重删处理。
    新写入数据是指对LUN开启重复数据删除功能后写入的数据。

    数据压缩特性(SmartCompression)是指在不丢失信息的前提下,通过对数据进行重新组织,缩减数据量以减少存储空间,提高存储系统的传输、处理和存储效率。存储系统支持的是在线压缩,即只对新写入的数据进行压缩处理。
    新写入数据是指对LUN开启重复数据删除功能后写入的数据。
    存储系统中,只有thin LUN才支持SmartDedupe&SmartCompressoion特性,请确保SmartThin特性的License文件可用。
    请在创建thin LUN时开启重复数据删除和数据压缩功能。否则,后续使用中无法正常使用SmartDedupe&SmartCompression特性。当某个LUN同时开启重复数据删除和数据压缩功能时,存储系统会对数据先进行重删,再进行压缩后才将数据写入硬盘。

    HyperLock(WORM)

    WORM特性又叫HyperLock特性,通过一次写入多次读取技术,保障原始数据在存储介质中的完整性、保密性及可存取性,满足日益增长的数据安全存储需求。
    背景
    随着科学技术的进步和社会发展,信息呈爆炸式增长,数据的安全访问和应用的问题逐渐受到人们的重视,例如法院案件、医疗病例、金融证券等,这些重要的数据按照法律规定在指定的时间周期内只能读不能写。因此需要对此类数据进行防纂改保护。WORM(Write Once Read Many)特性提供一次写入多次读取技术,是存储业界常用的数据安全访问和归档的方法,旨在防止数据被纂改,实现数据的备案和归档。

    定义
    WORM特性是指文件被写入完成后即可通过去掉文件的写权限,使其进入只读状态。在该状态下文件只能被读取,无法被删除、修改或重命名。通过配置WORM特性对存储数据进行保护后,可以防止其被意外纂改,满足企业或组织对重要业务数据安全存储的需求。

    具有WORM特性的文件系统(以下简称WORM文件系统)只能由管理员进行设置。根据管理员权限不同,WORM文件系统可分为法规遵从模式(Regulatory Compliance WORM,简称 WORM-C)和企业遵从模式(Enterprise WORM,简称 WORM-E)

    HyperMetro(双活)

    HyperMetro特性(又称双活特性),是双活数据中心解决方案的关键技术,可以提供给用户高级别的数据可靠性以及业务连续性。
    HyperMetro特性实现的仲裁原理、数据I/O原理。
    搭建双活数据中心的标准组网、仲裁服务器兼容性、多路径软件兼容性以及整体方案安装部署指导。
    HyperMetro特性又称双活特性(以下统称双活特性),双活特性中的两个数据中心互为备份,且都处于运行状态。当一个数据中心发生设备故障,甚至数据中心整体故障时,业务自动切换到另一个数据中心,解决了传统灾备业务无法自动切换的问题。提供给用户高级别的数据可靠性以及业务连续性的同时,提高存储系统的资源利用率。

    HyperVault(一体化备份)

    一体化备份特性又叫HyperVault特性。HyperVault(一体化备份)是利用快照和远程复制技术对存储系统的数据进行备份和恢复,既可以实现数据本地备份和本地恢复,也可以实现异地备份和异地恢复。
    定义
    HyperVault是基于文件系统实现的,实现了存储系统内和存储系统间文件系统数据的备份和恢复。

    HyperVault的数据备份包括本地备份和异地备份,通过文件系统的快照或远程复制技术,将某时刻数据按照设定策略备份到源端或者备份端存储系统。
    HyperVault的数据恢复包括本地恢复和异地恢复,通过文件系统的快照回滚或远程复制技术,指定某一个本地备份快照进行快照回滚或者指定某一个备份端存储系统的远程快照进行恢复。

    更多相关内容
  • 现代C++语言核心特性解析.pdf
  • 走在技术前沿之 Vue3.0 新特性全面解析。 全网抢先看,做首批 Vue 3.0 开发者!!! 课程内容包含: 1.Vue 3.0之版本大更新 2.新特性重点关注 3.composition-api(组合式API) 4.初始化Vue 3.0项目 5.setup函数...
  • C#之特性

    千次阅读 2022-01-24 22:49:00
    一、什么是特性特性是一种允许我们向程序的程序集添加元数据的语言结构。它是用于保存程序结构信息的特殊类型的类。 或者说 特性(Attribute)是用于在运行时传递程序中各种元素(比如类、方法、结构、枚举、...

    一、什么是特性?

    特性是一种允许我们向程序的程序集添加元数据的语言结构。它是用于保存程序结构信息的特殊类型的类。

    或者说

    特性(Attribute)是用于在运行时传递程序中各种元素(比如类、方法、结构、枚举、组件等)的行为信息的声明性标签。

    二、特性的使用

    由方括号,中间包裹着特性名和参数列表(也可以无参)。放置在它所要应用的元素之前(类前,方法前等等)。可以参考下面3个特性。

    [Serializable]
    [XmlRoot("MyClass")]
    public class MyClass
    {
        
        public int id;
    
        [NonSerialized]
        public string name;
    }
    

    三、特性的属性

    • 在一个元素(如类和属性,方法等等)上可以使用一个或多个特性进行修饰。
    • 特性可以拥有参数。
    • 程序可使用反射来检查自己的元数据或其他程序中的元数据。

    四、预定义的特性

    1.AttributeUsage特性

    声明特性能够应用于什么类型的程序结构,仅可用在特性声明上,也就是说只能在Attribute的派生类上生效。如下是Serializable特性源码,其在特性声明时使用了AttributeUsage特性。

    namespace System
    {
        [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Delegate, Inherited = false)]
        public sealed class SerializableAttribute : Attribute
        {
            public SerializableAttribute();
        }
    }
    

    关于AttributeTargets对应的字段可以参考官方文档

    AttributeUsage的公有属性:

    名字意义
    ValidOn保存能应用特性的目标类型的列表。构造函数的第一个参数是 AttributeTargets类型的枚举值
    Inherited指示特性是否可被装饰类型的派生类所继承
    AllowMultiple指示目是否可以给目标上多次指定指定的特性。

    使用举例,如下是一个自定义特性:

    [AttributeUsage(AttributeTargets.Class|AttributeTargets.Field,Inherited =true,AllowMultiple =true)]
        public sealed class MyCustomAttribute : Attribute
        {
            public MyCustomAttribute() 
            { 
            
            }
    
            public MyCustomAttribute(string name)
            { 
            
            }
        }
    
        [MyCustom("有参构造")]
        [MyCustom("有参构造2")]
        public class MyClass 
        {
            [MyCustom]
            public int id;
        }
    
    2.Obsolete特性

    当某些旧方法过时了,你不想要在使用这个方法了,可以用Obsolete特性来将程序结构标注为“过时”,并且在代码编译时会显示警告信息。下面是Obsolete特性的源码。

    namespace System
    {
        [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
        public sealed class ObsoleteAttribute : Attribute
        {
            public ObsoleteAttribute();
            public ObsoleteAttribute(string message);
            public ObsoleteAttribute(string message, bool error);
    
            public bool IsError { get; }
            public string Message { get; }
        }
    }
    

    从源码中,我们可以指定这个特性能够用在类,结构,枚举,构造,方法,属性,字段,事件,接口上。通过它的构造方法,我们可以知道它有三个重载。这个特性可以不传入参数,可以传入一个参数,也可以传入两个参数。

    下面是对这个特性的举例使用。
    例如使用一个参数的重载时,在MyClass类上标注[Obsolete("类已经过时")],代码编译时会显示警告“类已过时”。在NewMyClass的Sum方法上标注[Obsolete("方法已经过时,请使用NewSum()")],在调用Sum方法时,也会有相应的警告显示。

    [Obsolete("类已经过时")]
    public class MyClass
    {
        public void Sum()
        {
    
        }
    }
    
    public class NewMyClass
    {
        [Obsolete("方法已经过时,请使用NewSum()")]
        public void Sum()
        {
    
        }
    
        public void NewSum()
        {
    
        }
    }
    
    
    public class Program
    {
        static void Main(string[] args)
        {
            MyClass myClass = new MyClass();
            NewMyClass newMyClass = new NewMyClass();
            newMyClass.Sum();
            newMyClass.NewSum();
        }
    }
    

    在这里插入图片描述
    在这里插入图片描述

    虽然上面的代码,代码编译时显示了警告,但是代码仍然可以执行。而在使用两个参数的重载时,并将Obsolete的第二个参数设置为true时,将会标记为错误,如下所示。

    public class NewMyClass
    {
    
        [Obsolete("num", true)]
        public int num;
    
    }
    
    
    public class Program
    {
        static void Main(string[] args)
        {
            NewMyClass newMyClass = new NewMyClass();
            newMyClass.num = 1;
        }
    }
    

    在这里插入图片描述

    3.Conditional特性

    Conditional特性允许我们包括或排斥特定方法的所有调用。简单的讲它可以根据条件编译来进行方法调用。

    #define MyClass
    using System;
    using System.Diagnostics;
    
    
    namespace AttributesConditional
    {
        public class MyClass
        {
            [Conditional("MyClass")]
            public void MethodA(string msg)
            {
                Console.WriteLine(msg);
            }
    
            public void MethodB()
            {
                Console.WriteLine("进行中");
            }
    
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                MyClass myClass = new MyClass();
                myClass.MethodA("开始");
                myClass.MethodB();
                myClass.MethodA("结束");
    
                Console.ReadKey();
            }
        }
    }
    

    如上方代码所示,我们在代码的第一行定义一个编译符号(MyClass),即是#define MyClass,而在方法上使用这个特性[Conditional("MyClass")]并指定编译符号(MyClass)。运行程序,其结果如下所示。

    运行结果:

    开始
    进行中
    结束
    

    而当我们将第一行#define MyClass注释掉后,再次运行,结果如下:

    进行中
    

    通过观察,我们发现,当在代码第一行定义编译符号(如:#define MyClass 后,使用特性指定编译符号(如:[Conditional("MyClass")]),运行时会调用相应的方法(如:MethodA),而如果没有在第一行定义编译符号,那么相应的方法会被忽略,不会被调用。

    Conditional特性可以应用在方法和类上。当然这需要符合一定的规则。

    • 方法必须是类或结构体的方法
    • 方法必须为void类型。
    • 方法不能被声明为override,当可以标记为virtual。
    • 方法不能是接口方法的实现。
    • 类上使用必须是Attribute类的派生类。
    • 该特性允许使用多个。

    需要注意的是定义编译符号必须是在程序入口代码的文件的第一行。

    五、多个特性使用

    • 多层结构:
    [特性1(参数...)]
    [特性2(参数...)]
    
    • 逗号分隔
    [特性1(参数...),特性2(参数...)]
    

    如代码下面所示:

    [Serializable,Obsolete]
    public class MyClass
    {    
        private int num;
    }
    
    [Serializable]
    [Obsolete]
    public class MyClass
    {    
        private int num;
    }
    

    六、自定义特性

    除了预定义的一些特性,我们也可以根据需求来自定义一些特性。

    1.如何声明自定义特性。
    • 定义一个类并且这个类派生自System.Attribute
    • 类的名字以Attribute后缀结构
    • 为了安全性,可以用一个sealed修饰成一个密封类型(非必须的),以防止被其他类所继承(可以参考预定义特性的源码,其都被sealed所修饰)。

    例如下面代码:
    在这里插入图片描述
    那么如何使用呢?
    可以这样写[MyCustomAttribute],也可以简写为[MyCustom]。当然这里推荐是简写就行了。

    特性可以有公有成员,但是公有成员只能是:

    • 字段
    • 属性
    • 构造函数
    (1)构造函数

    如果在声明自定义特性的时候不声明构造函数,那么编译器会为你产生一个默认的无参构造。
    自定义特性的构造函数可以被重载。声明自定义特性构造和声明其他类一样,使用类名。例如下面所示。

    public sealed class MyCustomAttribute : Attribute
        {
            public MyCustomAttribute() 
            { 
            
            }
    
            public MyCustomAttribute(string name)
            { 
            
            }
        }
    

    当我们使用特性时,其实就是在指定使用哪个构造函数来创建特性的实例。使用如下。

    [MyCustom("有参构造")]
    public class MyClass 
    {
         [MyCustom]
         public int id;
    }
    
    (2)限制特性的使用

    有些预定义的特性限制了其使用范围,例如有的特性只能在类上使用,有的特性只能在字段上使用,这种限制是通过AttributeUsage来实现的,这在上面已经介绍过了。

    2.如何访问自定义特性

    就像在类中定义了属性,但是属性没有被调用,那么这个属性所蕴含的信息我们并不会知道。同理,仅仅声明了自定义特性,并且应用在某些程序结构上使程序结构和所应用的特性相关联,但是着仅仅相当于一个标识,我们并不没有检索这些特性蕴含的信息。所以,我们就需要通过某种反射的方式来访问自定义特性。

    (1)IsDefined方法

    IsDefined(Type, Boolean)检测某个特性是否应用到某个类上。

    • 第一个参数是需要检查的特性的Type对象
    • 第二个参数是指示是否搜索此成员的继承链来查找这个特性。

    下方示例是一个检测MyClass类上是否应用了一个MyCustom的特性,这就用到了IsDefined方法,其第一个参数就是要接受检查的MyCustomAttribute的Type对象,第二个参数就是指示是否搜索MyClass 的继承链来查找这个特性。

     [AttributeUsage(AttributeTargets.Class)]
        public sealed class MyCustomAttribute : Attribute
        {
            public MyCustomAttribute() 
            { 
            
            }
        }
    
        [MyCustom]
        public class MyClass 
        {
    
        }
    
        
        class Program
        {
            static void Main(string[] args)
            {
                MyClass myClass = new MyClass();
                Type type = myClass.GetType();
                bool isDefined = type.IsDefined(typeof(MyCustomAttribute), false);
                if (isDefined)
                    Console.WriteLine(type.Name+"上使用了特性MyCustom");
                Console.ReadKey();
            }
        }
    

    运行结构:

    MyClass上使用了特性MyCustom
    
    (2)GetCustomAttributes方法

    GetCustomAttributes(Boolean):返回应用到结构上的特性的数组。参数指定是否搜索继承链查找特性。
    GetCustomAttributes(Type, Boolean):返回应用到结构上的特性的数组。第一个参数,要搜索的特性类型。第二个参数,指定是否搜索继承链查找特性。

    [AttributeUsage(AttributeTargets.Class)]
        public sealed class MyCustomAttribute : Attribute
        {
            public string Name { get; set; }
            public int Num { get; set; }
    
            public MyCustomAttribute(string name,int num) 
            {
                Name = name;
                Num = num;
            }
        }
    
        [MyCustom("MyCustomDemo",1)]
        public class MyClass 
        {
    
        }
    
        
        class Program
        {
            static void Main(string[] args)
            {
                Type type = typeof(MyClass);
                object[] attArr = type.GetCustomAttributes(false);
                foreach (var att in attArr)
                {
                    MyCustomAttribute myCustomAttribute = att as MyCustomAttribute;
                    if (myCustomAttribute != null)
                    {
                        Console.WriteLine("name:"+myCustomAttribute.Name);
                        Console.WriteLine("num:"+myCustomAttribute.Num);
                    }
                }                
                Console.ReadKey();
            }
        }
    

    运行结果:

    name:MyCustomDemo
    num:1
    

    上面示例仅仅是针对类上的,那么针对字段的如何实现?

    [AttributeUsage(AttributeTargets.Class| AttributeTargets.Field)]
        public sealed class MyCustomAttribute : Attribute
        {
            public string Name { get; set; }
            public int Num { get; set; }
    
            public MyCustomAttribute(string name,int num) 
            {
                Name = name;
                Num = num;
            }
        }
    
        [MyCustom("MyCustomDemo",1)]
        public class MyClass 
        {
            [MyCustom("id", 2)]
            public string id;
        }
    
        
        class Program
        {
            static void Main(string[] args)
            {
                Type type = typeof(MyClass);
                FieldInfo[] fieldInfos = type.GetFields();
                foreach (var fieldInfo in fieldInfos)
                {
                    object[] attArr = fieldInfo.GetCustomAttributes(false);
                    foreach (var att in attArr)
                    {
                        MyCustomAttribute myCustomAttribute = att as MyCustomAttribute;
                        if (myCustomAttribute != null)
                        {
                            Console.WriteLine("name:" + myCustomAttribute.Name);
                            Console.WriteLine("num:" + myCustomAttribute.Num);
                        }
                    }
                }
    
                Console.ReadKey();
            }
        }
    

    通过上面代码,我们可以发现,字段的也是用GetCustomAttributes方法,不过不是通过type直接调了,而是通过先通过反射获取到字段,然后通过获取的字段引用调用GetCustomAttributes,接下来就和签名的一样了。

    那么同理,方法上也可以用类似的方法获取到数据。

    [AttributeUsage(AttributeTargets.Class| AttributeTargets.Field|AttributeTargets.Method)]
        public sealed class MyCustomAttribute : Attribute
        {
            public string Name { get; set; }
            public int Num { get; set; }
    
            public MyCustomAttribute(string name,int num) 
            {
                Name = name;
                Num = num;
            }
        }
    
        [MyCustom("MyCustomDemo",1)]
        public class MyClass 
        {
            [MyCustom("id", 2)]
            public string id;
    
            [MyCustom("method",3)]
            public void Method()
            { 
            
            }
        }
    
        
        class Program
        {
            static void Main(string[] args)
            {
                Type type = typeof(MyClass);
    
                MethodInfo[] methodInfos = type.GetMethods();
                foreach (var methodInfo in methodInfos)
                {
                    object[] attArr = methodInfo.GetCustomAttributes(false);
                    foreach (var att in attArr)
                    {
                        MyCustomAttribute myCustomAttribute = att as MyCustomAttribute;
                        if (myCustomAttribute != null)
                        {
                            Console.WriteLine("name:" + myCustomAttribute.Name);
                            Console.WriteLine("num:" + myCustomAttribute.Num);
                        }
                    }
                }
    
                Console.ReadKey();
            }
        }
    

    总结:我们可以通过反射的GetCustomAttributes方法来获取应用到结构上的特性的数组,来获取数据。无论是类,字段或是方法等等结构,我们都可以通过反射得到相应的结构引用,在通过结构的引用调用GetCustomAttributes方法来得到结构上的特性的数组,以此来得到相应的数据。

    七、最后

    我的学习总结就到这里,更多特性相关的可以参考官方文档

    展开全文
  • 详谈C#特性及应用

    千次阅读 2021-10-06 22:40:06
    详谈C#特性

    特性与反射息息相关,学习特性前,建议学习了解下这篇博客:C# 反射

    一、特性直观感受

    每一个特性都会带来对应得功能(其实这是个错觉)。

    如下图,两个特性使我们经常在开发中见到的,Obsolete 可以影响到编译器发出警告,Serializable 可以序列化和反序列化影响程序运行
    在这里插入图片描述

    二、声明,定义

    特性使用中括号声明,特性是一个类且必须直接或者间接继承 Attribute。

    看了 Obsolete 与 Serializable 特性使用后,F12 查看一下源码,可以看到这两个特性都是一个类并且继承 Attribute
    在这里插入图片描述在这里插入图片描述

    三、IL 语言特性

    特性添加后,编译会在元素内部产生 IL,但我们没有办法直接使用的,而且在 metadata 里面会有记录。

    这里定义了一个 CustomAttribute 特性,且声明到了 Product 类与其成员上,然后进行编译一下
    在这里插入图片描述使用反编译工具,在 bin 目录查看程序集(dll or exe),可以看到与我们写得 C# 源代码一样
    在这里插入图片描述
    在这里插入图片描述点开 Product 类,切换到 IL 语言,可一看到其成员,且在 C# 源代码标记过的地方,都编译成了特性的构造函数
    在这里插入图片描述


    四、特性本身无意义

    特性本身是没有用没有意义的。这句话,我们从程序运行也可以验证,下面是个一个简单的例子

    这里定义了 CustomAttribute ,且在构造函数里面打印了一句话,在实例化对象是会进行提示

    public class CustomAttribute: Attribute
    {
        public CustomAttribute()
        {
            Console.WriteLine("CustomAttribute 构造函数");
        }
    }
    
    

    再定义一个 Product 类,其被 CustomAttribute 声明

    [Custom]
    public class Product
    {
        [Custom]
        public int Id { get; set; }
    
        [Custom]
        public int GetId()
        {
            return Id;
        }
    }
    
    

    这里在 Main 函数,对类进行实例化,对属性赋值,且调用方法

    static void Main(string[] args)
    {
        Product product= new Product() { Id=1};
        Console.WriteLine(product.GetId());
    
        Console.ReadKey();
    }
    
    

    启动,可以看到,程序正常运行,且没有打印 Custom 特性相关的提示信息,所以特性本身是没有意义的。
    在这里插入图片描述


    五、特性 API

    特性本身是没有用的,程序运行过程中,我们能找到特性,而且也能应用一下。特性可以声明在类、方法、字段、属性、参数、返回值上,程序运行时可以获取到特性声明的信息。

    首先定义 CustomAttribute 特性,且包含 Desc 属性和两个构造函数

    public class CustomAttribute: Attribute 
    {
        public string Desc { get; set; }
    
        public CustomAttribute()
        {
            Console.WriteLine("CustomAttribute 构造函数");
        }
    
        public CustomAttribute(string desc)
        {
            Console.WriteLine("CustomAttribute 有参构造函数");
            Desc = desc;
        }
    }
    

    定义 Product 类,在其本身与成员及方法返回值全部声明 CustomAttribute

    [Custom("我在类上")]
    public class Product
    {
        [Custom("我在字段上")]
        public string name;
    
        [Custom("我在属性上")]
        public string Name { get; set; }
    
        [Custom("我在方法上")]
        [return:Custom("我在返回值上")]
        public string GetName([Custom("我在参数上")] int id)
        {
            return Name;
        }
    }
    

    在 Main 函数,写了一些特性实例化与获取信息的一些 API

    static void Main(string[] args)
    {
        Product product= new Product() { };
    
        Type type = typeof(Product);
        if (type.IsDefined(typeof(CustomAttribute), true))
        {
            CustomAttribute customAttribute = (CustomAttribute)type.GetCustomAttribute(typeof(CustomAttribute),true);
            Console.WriteLine(customAttribute.Desc);
        }
    
        MethodInfo method = type.GetMethod("GetName");
        if (method.IsDefined(typeof(CustomAttribute), true))
        {
            CustomAttribute customAttribute = (CustomAttribute)method.GetCustomAttribute(typeof(CustomAttribute), true);
            Console.WriteLine(customAttribute.Desc);
        }
    
        ParameterInfo parameter = method.GetParameters()[0];
        if (parameter.IsDefined(typeof(CustomAttribute), true))
        {
            CustomAttribute customAttribute = (CustomAttribute)parameter.GetCustomAttributes(typeof(CustomAttribute), true)[0];
            Console.WriteLine(customAttribute.Desc);
        }
    
        ParameterInfo returnParameter = method.ReturnParameter;
        if (returnParameter.IsDefined(typeof(CustomAttribute), true))
        {
            CustomAttribute customAttribute = (CustomAttribute)returnParameter.GetCustomAttribute(typeof(CustomAttribute), true);
            Console.WriteLine(customAttribute.Desc);
        }
    
        PropertyInfo property = type.GetProperty("Name");
        if (property.IsDefined(typeof(CustomAttribute), true))
        {
            CustomAttribute customAttribute = (CustomAttribute)property.GetCustomAttribute(typeof(CustomAttribute), true);
            Console.WriteLine(customAttribute.Desc);
        }
    
        FieldInfo field = type.GetField("name");
        if (field.IsDefined(typeof(CustomAttribute), true))
        {
            CustomAttribute customAttribute = (CustomAttribute)field.GetCustomAttribute(typeof(CustomAttribute), true);
            Console.WriteLine(customAttribute.Desc);
        }
    
        Console.ReadKey();
    }
    

    启动,可以看到在成员运行时,拿取到声明特性的各种信息
    在这里插入图片描述

    CustomAttribute customAttribute = (CustomAttribute)field.GetCustomAttribute(typeof(CustomAttribute), true); // 会实例化特性


    六、特性实际应用

    没有破坏封装的前提下,可以额外的加点消息与行为。

    说到这可能有的同学就问,上面说了那么多,在我们平时开发时有什么实际用处吗?答案是:有的,接下来使用实例进行讲解

    6.1、添加额外消息

    场景:分销系统,订单状态开发时通常喜欢使用枚举进行定义,但在 UI 展示其对于描述时有哪些做法呢?

    首先,订单状态枚举定义,这里进行简化

    public enum OrderStatus
    {
        /// <summary>
        /// 暂存
        /// </summary>
        TemporaryStorage = 0,
        /// <summary>
        /// 未审批
        /// </summary>
        NotApproved = 10,
        /// <summary>
        /// 已审批
        /// </summary>
        Approved = 20
    
        // 还有其他许多状态,这里不进行举例
    }
    

    第一种:手动维护,拼凑(还会有其他类似的写法,这里不进行一一举例)

    列表, 这里有的开发时写了一个类似 K-V 的集合,分表对值与描述进行了,平凑返回给 UI ,进行渲染 select 或者 list

    public static Dictionary<int, string> GetOrderStatusList()
    {
        Dictionary<int, string> orderStatus = new Dictionary<int, string>();
        orderStatus.Add(OrderStatus.Approved.GetHashCode(), "暂存");
        orderStatus.Add(OrderStatus.Approved.GetHashCode(), "未审批");
        orderStatus.Add(OrderStatus.Approved.GetHashCode(), "已审批");
        // 未来扩展状态流,都得手动进行添加
    
        return orderStatus;
    }
    

    表单,面对数据报表,单个状态对于的描述,通常使用一串的 if 进行获取

    public static string GetOrderStatusRemark(OrderStatus orderStatus)
    {
        if (orderStatus == OrderStatus.Approved)
        {
            return "暂存";
        }
        else if(orderStatus == OrderStatus.Approved)
        {
            return "已审批";
        }
        else if (orderStatus == OrderStatus.NotApproved)
        {
            return "未审批";
        }
        // 未来扩展状态流,都得手动进行添加
    
        return orderStatus.ToString();
    }
    

    特性方式:提高开发效率,且公用,易于维护,易于编码

    首先定义一个 RemarkAttribute 特性,使用 _Remark 承载我们的描述信息

    public class RemarkAttribute : Attribute
    {
        private string _Remark { get; set; }
    
        public RemarkAttribute(string remark)
        {
            _Remark = remark;
        }
    
        public string GetRemark()
        {
            return _Remark;
        }
    }
    

    在状态枚举成员打上特性,且输入每个状态的描述信息

    public enum OrderStatus
    {
        /// <summary>
        /// 暂存
        /// </summary>
        [Remark("暂存")]
        TemporaryStorage = 0,
        /// <summary>
        /// 未审批
        /// </summary>
        [Remark("未审批")]
        NotApproved = 10,
        /// <summary>
        /// 已审批
        /// </summary>
        [Remark("已审批")]
        Approved = 20
    
        // 还有其他许多状态,这里不进行举例
    }
    

    创建一个状态枚举的扩张类,写一个 GetRemark 扩张方法,用于取当前状态成员标记特性的描述信息

    public static class OrderStatusExtension
    {
        public static string GetRemark(this OrderStatus val)
        {
            Type type = val.GetType();
            FieldInfo field = type.GetField(val.ToString());
            if (field.IsDefined(typeof(RemarkAttribute),true))
            {
                RemarkAttribute remarkAttribute = (RemarkAttribute)field.GetCustomAttribute(typeof(RemarkAttribute), true);
                return remarkAttribute.GetRemark();
            }
            return val.ToString();
        }
    }
    

    启动,可以看到,成功从 Remark 特性成员 _Remark 字段获取到 NotApproved 状态的描述信息

    static void Main(string[] args)
    {
    
        OrderStatus orderStatus = OrderStatus.NotApproved;
        Console.WriteLine(orderStatus.GetRemark());
    
        Console.ReadKey();
    }
    

    在这里插入图片描述
    延展:平时开发程序,model 对于的表格或者表单的描述也可用此方法

    6.2、添加额外行为

    场景:表单提交,数据效验

    public class Personal
    {
        public string Name { get; set; }
    
        public string Address { get; set; }
    
        public long  QQ { get; set; }
    
        // 还有许多其他字段
    }
    

    第一种:这种写法最简单的,通常在 mvc 的 action 方法里面进行效验,在多个 action 中这种会造成代码重复,且维护困难

    Personal personal= new Personal() { QQ = 1};
    if (personal.QQ > 10001 && personal.QQ < 999999999999)
    {
    
    }
     // 还有更多 else if () 对其他进行效验
     
    

    第二种:由于第一种产生的问题,有的小伙伴会将验证逻辑放到 get set 访问器中,这种造成了职责不分明,实体本身是承载信息的,不需要存在业务逻辑

    public class Personal
    {
        public string Name { get; set; }
    
        public string Address { get; set; }
    
        public long QQ
        {
            get
            {
    
                return this.QQ;
            }
            set
            {
                if (value > 10001 && value < 999999999999)
                {
                    this.QQ = value;
                }
                else
                {
                    throw new Exception("QQ号不合法");
                }
            }
        }
    
        // 还有许多其他字段
    }
    

    特性方式:由于以上两种产生的问题,我们可以使用特性进行处理,易于维护、易于编码、易于公用

    定义一个 LongAttribute 特性,其中有个最小、最大字段,且有一个 Validate 方法用于处理效验逻辑

    public class LongAttribute : Attribute
    {
        private long _Min { get; set; }
        private long _Max { get; set; }
    
        public LongAttribute(long min,long max)
        {
            _Min = min;
            _Max = max;
        }
    
        public bool Validate(object val)
        {
            if (val != null && !string.IsNullOrEmpty(val.ToString()))
            {
                if (long.TryParse(val.ToString(),out long lResult))
                {
                    if (lResult > _Min && lResult < _Max)
                    {
                        return true;
                    }
                }
            }
            return false;
        }
    }
    

    定义一个实体类,有 Name、Address 、QQ 三个字段(实际比这多),在 QQ 字段标记特性 Long 并定义 min max

    public class Personal
    {
        public string Name { get; set; }
    
        public string Address { get; set; }
    
        [Long(1001, 99999999999)]
        public long QQ { get; set; }
    
        // 还有许多其他字段
    }
    

    定义一个 Validate 的扩张类与扩张方法,其作用是取得对象 Type 获取 LongAttribute 并调用其 Validate 进行业务逻辑效验

    public static class ValidateExtension
    {
        public static bool Validate(this object val)
        {
            Type type= val.GetType();
            foreach (var prop in type.GetProperties())
            {
                if (prop.IsDefined(typeof(LongAttribute),true))
                {
                    LongAttribute longAttribute = (LongAttribute)prop.GetCustomAttribute(typeof(LongAttribute),true);
                    if(!longAttribute.Validate(prop.GetValue(val)))
                    {
                    	return  false;
                    }            
                 }
            }
            return true;
        }
    }
    

    这里,分别实例化两个 Personal ,并对 QQ 字段赋予不合法与合法的值

    static void Main(string[] args)
    {
        Personal personal= new Personal() { QQ = 1};
        Console.WriteLine(personal.Validate());
        
        Personal personal1= new Personal() { QQ = 100000};
        Console.WriteLine(personal1.Validate());
    
        Console.ReadKey();
    }
    

    启动,可以看到对效验的结果,分别返回了 false true 成功的进行了效验
    在这里插入图片描述

    有人要问只验证个 QQ 有啥意义?且慢,我们还可以多名字等其他字段进行验证,接着我们对 name 字段进行效验

    定义一个 LengthAttribute 特性,定义 min max 两个成员,Validate 方法进行业务逻辑效验

    public class LengthAttribute : Attribute
    {
        private long _Min { get; set; }
        private long _Max { get; set; }
    
        public LengthAttribute(long min, long max)
        {
            _Min = min;
            _Max = max;
        }
    
        public bool Validate(object val)
        {
            if (val != null && !string.IsNullOrEmpty(val.ToString()))
            {
                if (val.ToString().Length > _Min && val.ToString().Length < _Max)
                {
                    return true;
                }
            }
            return false;
        }
    }
    
    

    在 name 字段打上 Length 特性,且定义 min = 1,max =10

    public class Personal
    {
        [Length(1, 10)]
        public string Name { get; set; }
    
        public string Address { get; set; }
    
        [Long(1001, 99999999999)]
        public long QQ { get; set; }
    
        // 还有许多其他字段
    }
    
    

    在 ValidateExtension 类 Validate 方法添加一个 LengthAttribute 特性的检查

    public static class ValidateExtension
    {
        public static bool Validate(this object val)
        {
            Type type= val.GetType();
            foreach (var prop in type.GetProperties())
            {
                if (prop.IsDefined(typeof(LongAttribute),true))
                {
                    LongAttribute longAttribute = (LongAttribute)prop.GetCustomAttribute(typeof(LongAttribute),true);
                    if(!longAttribute.Validate(prop.GetValue(val)))
                    {
                    	return false;
                    }
                }
                if (prop.IsDefined(typeof(LengthAttribute), true))
                {
                    LengthAttribute longAttribute = (LengthAttribute)prop.GetCustomAttribute(typeof(LengthAttribute), true);
                    if(!longAttribute.Validate(prop.GetValue(val)))
                    {
                    	return false;
                    }
                }
            }
            return true;
        }
    }
    
    

    实例化 Personal ,对 name 字段进行赋值

    static void Main(string[] args)
    {
    
        Personal personal= new Personal() { Name = "张三"};
        Console.WriteLine(personal.Validate());
    
        Personal personal1= new Personal() { Name = "张"};
        Console.WriteLine(personal1.Validate());
    
        Console.ReadKey();
    }
    
    

    启动,可以看到,根据标记的特性正确的进行了检测
    在这里插入图片描述
    抽象

    public class AbstractValidateAttribute : Attribute
    {
        public virtual bool Validate(object val) => false;
    }
    
    
    public class LongAttribute : AbstractValidateAttribute
    {
        private long _Min { get; set; }
        private long _Max { get; set; }
    
        public LongAttribute(long min, long max)
            {
                _Min = min;
                _Max = max;
            }
    
        public override bool Validate(object val)
            {
                if (val != null && !string.IsNullOrEmpty(val.ToString()))
                {
                    if (long.TryParse(val.ToString(), out long lResult))
                    {
                        if (lResult > _Min && lResult < _Max)
                        {
                            return true;
                        }
                    }
                }
                return false;
            }
    }
    
    
    
    public class LengthAttribute : AbstractValidateAttribute
    {
        private long _Min { get; set; }
        private long _Max { get; set; }
    
        public LengthAttribute(long min, long max)
            {
                _Min = min;
                _Max = max;
            }
    
        public override bool Validate(object val)
        {
            if (val != null && !string.IsNullOrEmpty(val.ToString()))
            {
                if (val.ToString().Length > _Min && val.ToString().Length < _Max)
                {
                    return true;
                }
            }
            return false;
        }
    }
    
    
    static void Main(string[] args)
    {
        Personal personal= new Personal() { Name = "张",QQ = 9999999};
        Console.WriteLine(personal.Validate());
    
        Personal personal1 = new Personal() { Name = "张三", QQ = 1 };
        Console.WriteLine(personal1.Validate());
    
        Personal personal2 = new Personal() { Name = "张三", QQ = 9999999 };
        Console.WriteLine(personal2.Validate());
    
        Console.ReadKey();
    }
    

    在这里插入图片描述

    展开全文
  • 序言 关于JDK11,自从去年也就是2018年9月份 Oracle 对外公布——JDK11正式发布以来,博主就跃跃欲试,但是由于项目周期时间紧,... 新特性概览 -> 详细文档说明 -> 官方 API -> 实践与应用(除了体验新...

    序言

    关于JDK11,自从去年也就是2018年9月份 Oracle 对外公布——JDK11正式发布以来,博主就跃跃欲试,但是由于项目周期时间紧,一直未果,今年,也就是2019年2月底系统正式上线,博主除了远程技术支持以外,终于可以抽出实现来一探究竟了,博主的探寻的起始之路如下:社区 -> 新特性概览 -> 详细文档说明 -> 官方 API -> 实践与应用(除了体验新特性带来的便利和快感之外,还思考解决了哪些实际的问题等)。

    关于如何开始 JDK11 的写作也是徘徊了良久,不知道该从哪儿开始,是从常用API呢,还是从代码实战,之后想来还是从JDK11新特性概论开始吧,在接下来的 “ Java11新特性 ” 系列文章中,如果有不到之处,欢迎指正,博主会立即予以修改。

    JDK11新特性概述

    1、关于JDK11

    JDK11是由Java Community Process中的JSR-384指定的 Java SE 平台版本 11 的开源引用实现。

    JDK11于2018年9月25日发布。在 GPL 下可用于生产的二进制文件可以从 Oracle 官方获得;此版本的特性和时间表是通过 JEP 流程提出并跟踪的,JEP 2.0提案对其进行了修订。该版本使用 JDK Release Process(JEP 3)生成的。

     

    2、JDK11的17项新特性

    1. 181: Nest-Based Access Control
    2. 309: Dynamic Class-File Constants
    3. 315: Improve Aarch64 Intrinsics
    4. 318: Epsilon: A No-Op Garbage Collector
    5. 320: Remove the Java EE and CORBA Modules
    6. 321: HTTP Client (Standard)
    7. 323: Local-Variable Syntax for Lambda Parameters
    8. 324: Key Agreement with Curve25519 and Curve448
    9. 327: Unicode 10
    10. 328: Flight Recorder
    11. 329: ChaCha20 and Poly1305 Cryptographic Algorithms
    12. 330: Launch Single-File Source-Code Programs
    13. 331: Low-Overhead Heap Profiling
    14. 332: Transport Layer Security (TLS) 1.3
    15. 333: ZGC: A Scalable Low-Latency Garbage Collector(Experimental)
    16. 335: Deprecate the Nashorn JavaScript Engine
    17. 336: Deprecate the Pack200 Tools and API
       

    光阴似箭、日月如梭,在过去的几个月中,Oracle 宣布了 Java 平台的改进,以确保其继续向前发展,为用户提供一个充满活力的未来。这些进展包括:

    • 提高交付的速度和可预测性:自Java9发布以来,Java平台已经切换到6个月的发布周期,允许开发人员更快地访问持续增强的功能。现在发行版在每年的3月和9月发布,这意味着不再试图每隔几年就一次性的数百个变更——相反,变更是以更有节制和可预测的速度发布的。
    • 使Java更加开放:为了提高开发人员的工作效率,Oracle采用了以前只能通过付费许可才能获得的商业特性,并将其开源。这样做可以在Oracle JDK和Oracle OpenJDK发行版之间创造更大的一致性和互换性。OpenJDK中以前的商业特性包括:Application Class Data Sharing、Project ZGC、 Java Flight Recorder (JFR)和 Java Mission Control (JMC)。最近,Oracle又宣布计划将JMC技术作为单独的下载提供给OpenJDK和Oracle JDK用户。
    • 关于Java SE订阅:Oracle 在今年夏天宣布了Java SE订阅,这是一个全新的模型,它涵盖了所有Java SE许可和支持,以进一步支持全球数百万在生产中运行Java的企业。订阅是对长期免费提供的Oracle OpenJDK的补充,它使开发人员和组织不需要商业支持。

    Oracle 提供的 JDK 不仅包括 Oracle OpenJDK 版本中的开源 GNU 通用公共许可协议版本 v2,还包括 Classpath Exception (GPLv2 + CPE) ,还包括那些使用 Oracle JDK 作为 Oracle 产品或服务的一部分或者不希望使用开源软件的用户的商业许可。 这些许可协议取代了历史上的“ BCL ”许可协议,该协议主要包含了免费和付费的商业条款。这样以来,将意味着用户可以得到符合自己需求的 Java 11:

    1. Java 11是一个长期支持(LTS)版本。这意味着那些对平台采用持保守态度并需要长期支持的用户可以通过Java SE订阅提供许可Oracle JDK二进制文件。它允许用户在至少8年内获得Java 11 LTS发行版的更新。订阅可以直接从Oracle访问经过测试和认证的Java SE性能方面、稳定性方面和安全性方面的更新。它还包括对 My Oracle Support (MOS)24x7的访问、对27种语言的支持、Java SE 8桌面管理、监控和部署特性等。
    2. 相反,喜欢快速访问新增强功能的用户可以继续使用Oracle OpenJDK发行版。与Java 9和Java 10相同,这个版本的用户将得到彻底的测试,由 Oracle 提供开源的 OpenJDK 来构建。

     

    Java 11提供了17个增强功能,其中最显著的包括:

     

    JDK随时间变化的总体速度在多年来基本上保持不变,但是在新的节奏下,更改速度已经显著增加。不是每隔几年就在一个庞大的发行版中提供成千上万个补丁和大约100个JEPS,而是在更小的发行版中以更易于管理、更可预测的进度提供更改。这些更改的范围从大的特性到小的增强、日常维护、BUG修复再到文档改进等。每个这样的更改都会在单个提交中表示。

    在 JDK11 中标记为已修复的2468个 JIRA 问题中,1963个 JIRA 问题是由 Oracle 工作人员完成的,其中 505 个由个人和其他组织的开发人员完成的。 仔细研究这些问题并整理委托人提供的组织数据,会得到下面的图表,主要展示了 JDK11 修复的组织:

    如上图,在JDK 11的开发过程中,Oracle 的开发人员解决了80% 的 JIRA 问题,而其它组织的开发人员解决了20% 的 JIRA 问题。 其中排名第二的五大贡献组织机构包括:SAP (7%)、 Red Hat (5%)、 Google (3%)、 BellSoft (1%)和 IBM (1%) ,这五大贡献机构共同解决了 17% 的 JIRA 问题,独立开发人员对JDK 11修复的贡献值为2% 。

    其余 1% 的 JIRA 问题修复是由:阿里巴巴、亚马逊(Amazon)、ARM、Azul、英特尔(Intel)、JetBrains、Linaro和Qualcomm Datacenter Technologies 等众多组织机构的开发人员共同完成的。

     

    3、产品支持路线图

    Oracle Java SE支持路线图(这个较之前的时间表有所变化,该表更新与2018年11月):

    对于Java SE 8之后的产品版本,Oracle将每三年指定一个版本作为长期支持(Long-Term-Support,LTS)版本。Java SE 11 (18.9 LTS)是一个LTS版本。出于Oracle Premier Support的目的,非LTS版本被认为是对最新LTS版本的实现增强的累积集。一旦一个新的特性发布可用,任何以前的非LTS发布都将被认为是可替代的。例如,Java SE 9是一个非 LTS 版本,并立即被Java SE 10(也是非LTS)所取代,而Java SE 10又立即被Java SE 11所取代。然而,Java SE 11是一个LTS版本,因此即使在 Java SE 12 发布之后,Oracle 客户也会收到 Oracle 官方获得支持和定期更新的Java版本。

     

    4、JavaFX & Web 部署技术

    与JRE绑定的Web部署技术(由Java插件和Java Web Start组成)具有更短的支持生命周期(只有5年的支持周期)。而在Java SE 9和Java SE 10中,部署堆栈被标记为不推荐的,并被标记为将要删除的。Oracle Java SE 11及其后续版本已经不包含部署堆栈。由于Java SE 8将是Java SE 8上的Java Web Start扩展支持的部署堆栈的结束版本,所以Java SE 8d 扩展支持预计在2025年3月结束。而对 Java 插件(JavaApplet)的支持将持续到2019年3月。

    Java SE 8是推荐的,也是唯一支持部署堆栈的版本。Java SE 8部署堆栈可用于在Windows平台上运行Java SE 6或Java SE 7应用程序。Java SE 8之外,其它 Java 部署技术将不再被支持。

    JavaFX已经开源并重新设计为一个独立的库,而不是包含在JDK中。从Java SE 11 (18.9 LTS)开始,JavaFX不再包含在Oracle JDK中。在Java SE 8上对JavaFX的支持将持续到Premier Support支持期(直到2022年3月)。

     

    Oracle Java SE 常见问题

    今年1月,也就是2019年1月,Oracle 官方发布了几个关注度较高的问题,并予以详细的回答,具体内容如下:

    问题一:2019年1月以后Java还免费吗?

    答案是绝对的。与过去20多年的情况一样,Oracle一直保持Java的免费和开放,并免费为当前版本提供稳定性方面、性能方面和安全性方面的持续更新。Oracle还将继续提供免费的关键补丁更新(需要提前一年预定),必要时提供额外的更新,并且在基于新版本更新的节奏下每年提供两个特性更新(还包括关键补丁更新)。 在 OpenJDK 开源社区中完成了所有这些开发工作,使得我们的贡献可以被任何人移植、分析和使用,作为开放源码的Java,可以从 Oracle 官网免费下载 Java 的最新更新版本。

     

    问题二:Java 8 的 “ End of Public Updates ” 时间表是什么?

    2019年1月15日计划对Java 8进行关键补丁更新(8u201和相关的8u202补丁集更新),这是BCL许可下的最后一次更新,BCL许可一般免费用于桌面和服务器,多年来一直是Oracle JDK许可。接下来,于2019年4月16日发布的Java 8更新(8u211和相关的8u212补丁集更新)将根据新的许可提供,该许可将免费用于个人桌面使用,并可用于开发、测试、原型设计和演示的目的。

    最近发布的 Java 版本仍然是免费的,并且遵循来自jdk.java.net的开源许可下,或者免费使用于OTN许可的开发、测试、原型设计和演示。2019年4月16日之后,对于那些希望继续使用发布的用于商业或生产目的的 java8 更新的用户,可以使用 Java SE 订阅。

     

    问题三: 在2019年4月前发布并在 BCL 下下载的 java8更新能否在2019年1月后继续使用?

    当然是可以的。可以根据提供的给定的许可条款继续使用任何版本的 Java。 Java 8更新的新许可只适用于2019年1月之后根据新许可发布的更新,从2019年4月16日计划的季度更新开始。

     

    总结

    在较早的 Java 公共更新中,可以一直追溯到 Java 1.1,可以在 Java 档案中找到。 提供这些旧版本是为了帮助开发人员在旧系统中调试问题。

    而在没有更新最新的安全修补程序情况下,博主不建议在公共网络种使用旧的或更老的版本,因为在没有更新安全补丁的情况下使用,是不安全的,需要承担风险之大。如果在政府级别的项目,对其稳定性要求比较高的,可以使用,因为一般政府的项目运行都是内网与外网隔离的,所以,不会存在安全性的问题,除非人为因素造成。

     

     

     

    参考 & 推荐阅读:

    《 Oracle Java SE 官网 》

    《 Oracle生命周期支持策略 》


     好了,关于 Java11新特性(一)——JDK11新特性概述 就写到这儿了,如果还有什么疑问或遇到什么问题欢迎扫码提问,也可以给我留言哦,我会一一详细的解答的。 
    歇后语:“ 共同学习,共同进步 ”,也希望大家多多关注CSND的IT社区。


    作       者:华    仔
    联系作者:who.seek.me@java98k.vip
    来        源:CSDN (Chinese Software Developer Network)
    原        文:https://blog.csdn.net/Hello_World_QWP/article/details/88788021
    版权声明:本文为博主原创文章,请在转载时务必注明博文出处!
    展开全文
  • 一、物理层 概述、 二、物理层 基本概念、 三、物理层 特性
  • 幅频特性和相频特性的物理意义

    千次阅读 2021-12-23 20:07:49
    一个系统的频率特性指的是对通过该系统的信号的不同频率分量产生的影响。 这种影响体现在:1)对输入信号的不同频率分量造成幅度上的比例放大或缩小;2)对输入信号的不同频率的分量造成相位上的偏转。 系统对输入...
  • 传输线特性阻抗计算方式

    千次阅读 2020-12-24 05:47:41
    也就是说,对于高频信号或高速数字信号的传输用的PCB之电气测试,不仅要测试线路的“通”、“断”、“短路”等是否合乎要求,而且还要其“特性阻抗值”是否合乎要求,只有这两方面都“合格”了,PCB才符合允收性。...
  • CAD快捷特性特性匹配

    万次阅读 2021-01-14 12:55:44
    原标题:CAD快捷特性特性匹配在CAD中,绘制的每一个图形对象都具有自己的特性,有些特性是基本特性,适用于多数的对象,例如,图层、颜色、线型和打印样式。有些特性是专用于某个对象的特性,例如,圆的特性包括...
  • 原标题:CAD快捷特性特性匹配在CAD中,绘制的每一个图形对象都具有自己的特性,有些特性是基本特性,适用于多数的对象,例如,图层、颜色、线型和打印样式。有些特性是专用于某个对象的特性,例如,圆的特性包括...
  • PostgreSQL 14 版本发布,快来看看有哪些新特性

    万次阅读 多人点赞 2021-05-22 22:12:21
    PostgreSQL 全球开发组于 2021-05-20 发布了 PostgreSQL 14 的第一个 beta 版本。本文介绍了该版本中的主要新特性和增强功能,包括性能、新的 multirange 类型、SQL 语句、管理、复制和恢复、安全以及其他方面。
  • 超声波的四个特性及应用特性

    千次阅读 2021-01-13 15:27:06
    超声波的四个特性及应用特性超声波顾名思义,超过常规声波的声波。声波是指人耳能感受到的一种纵波,其频率范围为16Hz-20KHz。当声波的频率低于16Hz时就叫做次声波,高于20KHz则称为超声波声波。超声波特性有四个...
  • 幅频特性和相频特性

    万次阅读 2021-03-20 22:00:13
    幅频特性和相频特性 G(jω)称为频率特性,A(ω)是输出信号的幅值与输入信号幅值之比,称为幅频特性。 Φ(ω)是输出信号的相角与输入信号的相角之差,称为相频特性。 相移角度随频率变化的特性叫相频特性。 由于放大...
  • 电阻元件的伏安特性 电阻元件的伏安特性实验结果误差分析一般做实验要有(1)实验名称;(2)实验目的;(3)实验原理;(4)实验电路图;(5)实验的步骤和方法;(6)实验结论;(7)老师评语; 以上7步不知道你要那部分;这些都...
  • Matlab绘制频率特性

    千次阅读 2021-08-13 15:25:01
    【自控笔记】5.2频率特性的四种表现方式及Matlab绘制 系统的频率特性G(jω)可以用函数形式表示,也可以用图形和曲线表示。它们分别是频率特性图、幅相特性图、对数频率特性图、对数幅相特性图。四种表示方式对比如下...
  • 尚硅谷Java8新特性下载

    热门讨论 2017-01-22 11:30:18
    尚硅谷 Java8 新特性 百度云下载链接
  • 数据库ACID四大特性到底为了啥,一文带你看通透

    千次阅读 多人点赞 2021-05-06 13:44:38
    说起数据库四大特性,同学们张口就来,ACID!那为什么要ACID?每种特性的原理又是什么?如何实现的?废话少说,哈哥今天带你搞清楚,快上车!
  • 电阻伏安特性曲线实验报告.docx

    千次阅读 2021-06-28 14:04:55
    电阻伏安特性曲线实验报告实验一 电子元件伏安特性的测定 一、实验目的 1.掌握电压表、电流表、直流稳压电源等仪器的使用方法2.学习电阻元件伏安特性曲线的测量方法 3.加深理解欧姆定律,熟悉伏安特性曲线的...
  • C++11新特性总结

    千次阅读 2022-03-22 16:12:11
    C++11新特性包括auto、decltype、constexpr、右值引用、move()函数、完美转发、移动构造、lambda匿名函数、for循环新格式、nullptr、shared_ptr、weak_ptr、unique_ptr、using定义别名、函数模板默认参数、tuple元组...
  • 雷达目标特性丛书(pdf扫描版)

    热门讨论 2011-02-27 13:54:06
    本书以雷达目标作为雷达的被测对象,系统地阐述了雷达目标特征、特性和仿真技术。其主要内容包括:雷达散射截面理论基础、各类目标的雷达散射截面、雷达散射截面起伏统计模型、雷达散射截面的减缩、雷达目标噪声、...
  • 不同温度和光照强度下的光伏阵列输出特性曲线,包括P-V和I-V特性曲线,运行即可看到曲线,建议使用2010b及以上版本运行
  • 事务的四大特性

    千次阅读 2022-03-22 10:42:42
    事务的特性 事务的四大特性:原子性、一致性、隔离性、持久兴; 原子性 事务的原子性是指事务必须是一个原子的操作序列单元。事务中包含的各项操作在一次执行过程中,只允许出现两种状态之一,要么都成功,要么都...
  • C# 特性(Attribute)是用于在运行时传递程序中各种元素(比如类、方法、结构、枚举、组件等)的行为信息的声明性标签。您可以通过使用特性向程序添加声明性信息。一个声明性标签是通过放置在它所应用的元素前面的方...
  • 记忆是学习的基础,如何记忆知识我们还是要研究的,场效应管一共有6种,其特性曲线还是很复杂的,要记忆也要花费很多精力,如下: 太多了,将它们画到一个图中吧: *上2图为转载 这个要好多了,但是还是有些乱,我们...
  • Oracle 19c十大新特性

    千次阅读 2020-01-16 07:30:00
    eygle对Oracle 18c、19c和20c十大新特性做了介绍,https://www.eygle.com/archives/2019/10/oracle_database_20c_...
  • c++三大特性

    千次阅读 2021-12-06 15:39:31
    C++的三大特性为:继承,多态,封装 封装可以隐藏实现细节,使得代码模块化, 继承可以扩展已存在的模块,它们目的都是为了: 代码重用。 而多态是为了实现另一个目的: 接口重用。 (1)继承。 一个对象直接使用另...
  • Lua 5.4 新特性概览

    千次阅读 2020-07-08 14:35:36
    本文简单介绍了一些 Lua 5.4 的新特性 Lua 5.4 正式发布了,很多朋友应该会比较好奇 Lua 5.4 与之前版本的区别,本文就此简单介绍一些 Lua 5.4 的新特性. 完整的 Lua 5.4 变更列表可以在这里找到,本文我们仅简单概览...
  • 深入体验JAVA Web开发内幕-高级特性.pdf深入体验JAVA Web开发内幕-高级特性.pdf深入体验JAVA Web开发内幕-高级特性.pdf深入体验JAVA Web开发内幕-高级特性.pdf深入体验JAVA Web开发内幕-高级特性.pdf深入体验JAVA ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,108,621
精华内容 1,243,448
关键字:

特性