烦人的Null,你可以走开点了

kettle使用常见问题解决-01 阅读详情

1. Null 的问题

假设现在有一个需要三个参数的方法。其中第一个参数是必须的,后两个参数是可有可无的。

第一种情况,在我们调用这个方法的时候,我们只能传入两个参数,对第三个参数,我们在上下文里是没有的,那么我们调用方法的时候,就需要用一个特殊值去告知这个方法:
第三个参数我们拿不到,参数是不存在或者不明确的。
这个特殊的值应该用什么呢?在 Java 中,我们会选择用 null 去表示这种情况。

第二种情况,如果在调用方法的时候,我们有三个参数,只是第三个参数没有值,我们也需要传入一个特殊的值去表示:
参数存在,但是没有值。
这个特殊的值是什么呢?没错,在 Java 中,又是 null。

你看到了,现在 null 值的含义本身出现了两个意思:

  1. 参数不存在
  2. 参数没有值

二义性在计算机科学里是能避免就尽量避免的。所以,null 值的二义性是一个 Java 中的设计缺陷。不过,也不光是在 Java 语言中,null 的二义性在编程语言里是广泛存在的一个问题。这个问题被称为 Null 引用问题。

Null 引用是计算机科学中一个历史悠久又臭名昭著的问题。在 1964 年,由快排算法的创造者东尼·霍尔发明。他自称这是个十亿美元的错误。

在 Java 中,当我们去调用一个对象值为 null 的方法或者属性时,就会报 java.lang.NullPointerException,简称为 NPE。

传统上,这些 NPE 问题,必须完全依赖程序员本身细致周密的检查,对于 null 的检查充斥在了 Java 代码的字里行间,让代码变得臃肿丑陋,非常恶心。

同时,由于 NPE 的二义性问题,开发人员往往无法完全防护住 NPE,这使得 NPE 成为了开发人员的噩梦。明明逻辑上,一个对象是存在的,只是不知道其明确含义,但是只要引用了这个没有明确含义值的对象的方法,就会被告知NPE,简直让人防不胜防。

并且,更可恶的是,在 Java 中,NPE 是运行期异常,这就意味着 NPE 无法早期发现,只有上线运行了,才可能出现问题。

烦人的Null,你可以走开点了

 

讨厌的 null,成本巨大的 NPE,让 Java 开发人员在不断地实践中,采用了各种方法去对付 null,让我们看看这些方法。

NPE 是运行期异常,只会在系统运行期间造成,所以导致代码检查无法提前发现它。如果我们能想办法把在运行期出现的 NPE,提前在编译代码时探测到,那么我们就会大大减轻 NPE 对系统造成的损害。

于是,@NonNull 这个注解横空出世了。

2. 横空出世的注解

@NonNull 这个注解就是一个标记,这个标记可以和 IDE 联动:当可能出现 NPE 时,IDE 会标出警告。

我们先看一段代码:

烦人的Null,你可以走开点了

 

上面的代码没有加入 @NonNull,可以看到 IDE 并没有给出什么警告。

让我们加上 @NonNull 注解看看:

烦人的Null,你可以走开点了

 

可以看到,Idea 和 @NonNull 注解形成了联动,并给出了可能出现 NPE 的警告。

有了这个警告,其实对一个复杂的项目来说还不够,因为这些警告很容易就会被忽略过去了,即使忽略了,项目依然可以编译运行起来。

那么,我们是不是可以再增加一步检查?当检查到了可疑的 NPE,根本不允许编译通过。是时候给大家介绍一下 findbugs 了!

3. findbugs 出场了

我们先在 maven 中配置好 findbugs:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.github</groupId>
    <artifactId>leetcodeMaster</artifactId>
    <version>1.0-SNAPSHOT</version>
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory> <!--扫描resources包下的配置文件-->
                <filtering>true</filtering>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/java</directory><!--扫描java包下的配置文件-->
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>findbugs-maven-plugin</artifactId>
                <version>3.0.5</version>
                <configuration>
                    <!-- 设置分析工作的等级,可以为Min、Default和Max -->
                    <effort>Low</effort>
                    <!-- Low、Medium和High (Low最严格) High只扫描严重错误。建议用Medium-->
                    <threshold>Medium</threshold>
                    <failOnError>true</failOnError>
                    <includeTests>true</includeTests>
                    <!--findbugs需要忽略的错误的配置文件-->
<!--                    <excludeFilterFile>conf/findbugs-exclude-filter.xml</excludeFilterFile>-->
                    <!--findbugs需要忽略的错误的配置文件-->
                    <includeFilterFile>conf/findbugs-include-filter.xml</includeFilterFile>
                </configuration>
                <executions>
                    <execution>
                        <id>run-findbugs</id>
                        <!-- 在package(也可设为compile) 阶段触发执行findbugs检查,比如执行 mvn clean package -->
                        <phase>compile</phase>
                        <goals>
                            <goal>check</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>19.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.3.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.google.code.findbugs/jsr305 -->
        <dependency>
            <groupId>com.google.code.findbugs</groupId>
            <artifactId>jsr305</artifactId>
            <version>3.0.2</version>
        </dependency>
    </dependencies>
</project>

紧接着运行maven,对项目进行编译。
mvn clean compile findbugs:findbugs 

烦人的Null,你可以走开点了

 

可以看到,findbugs 发现可能会在运行期间出现 NPE 后,中断了项目构建过程。

我们再打开 findbugs 的界面看看具体的报错位置:

烦人的Null,你可以走开点了

 

你瞧,findbugs 准确的找到了可能出现 NPE 的根源。

通过以上这些手段,我们尽可能的将 NPE 提前到编译期发现。

但是啊但是,对一个规模庞大且复杂的项目来说,光使用静态代码检查还是不够的。因为类似 findbugs 这种的静态代码检查工具,不可能对每个 NPE 的检查点都检查到位。并且,探测的问题有时候因为业务原因,也会放松检查要求。

别慌,我们可以让静态代码检查再加上一些别的方法,来联手堵住 NPE 问题,这就是我们下面要说的 Optional。

4. 用 Optional 去除二义性

由于铺天盖地的 null 检查,使得 Java 程序员叫苦不堪。于是官方自 Java8 起,参考了 google 的 guava,引入了 Optional 类型用来避免每次繁琐丑陋的 null 检查。

Optional 本质上就是一个容器,这个容器持有了一个变量类型为 T 的值。所以,Optional 这个容器中的值只会有两种情况,要么为类型 T 的变量值,要么为null。

对于可能出现的为 null 的情况,Optional 本身从创建、检查,到抽取、使用,都提供了对应的方法供使用者调用。并采用了意义很明确的方法去排除了null的二义性。

我们看示例代码:

class Player{
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

public class Optional4NPE {
    public static void main(String[] args) {
        Optional<Player> optionalPlayer = Optional.ofNullable(null);
        optionalPlayer.ifPresent(u -> System.out.println(u.getName()));
    }
}

以上代码我们使用了一个 Optional 中的 ofNullable,去创建了一个包含了类型为 Player、值为 null 的 Optional 容器。

运行结果:
'Process finished with exit code 0'

运行后,代码没有任何输出,也没有出现 NPE 异常。没有输出的原因是我们传入了一个 null 值,这个 null 表示值不存在。此时,我们调用 Optional 的 ifPresent 方法做了判断,只有存在值时,才会执行打印输出。

接下来,我们把 null 替换成有意义的值看看。

import java.util.Optional;

class Player{
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

public class Optional4NPE {
    public static void main(String[] args) {
        Player player = new Player();
        player.setId(1);
        player.setName("demoUser");
        Optional<Player> optionalPlayer = Optional.ofNullable(player);
        optionalPlayer.ifPresent(u -> System.out.println(u.getName()));
    }
}

输出结果:

demoUser

Process finished with exit code 

可以看到,当传入一个我们创建的 player 时,执行了打印输出方法。

上面我们已经发现,通过 Optional 的 ifPresent 方法,我们明确了 null 的含义,明确认定只要值为 null,就表示不存在。那如果一个变量存在,但是没有值或者没有有意义的值呢?

我们把代码改改:

import java.util.Optional;

class Player{
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

public class Optional4NPE {
    public static void main(String[] args) {
        Player player = null;
        Player defaultPlayer = new Player();
        defaultPlayer.setId(1);
        defaultPlayer.setName("————undefinedNAME-----");
        Player player1 = Optional.ofNullable(player).orElse(defaultPlayer);
        System.out.println(player1.getName());
    }
}

运行结果如下:

————undefinedNAME-----

Process finished with exit code 0

这里可以看到,我们使用 orElse 方法,当一个变量值为 null 时,返回一个默认值。通过返回默认值,我们明确了 null 的另外一个含义,对象存在,但是可能没有实际意义。

Optional 的出现,大大改善了我们的 Java 代码质量,减少了 NPE 的可能性,并使得代码的可读性大大增强。

通过使用 Optional,开发人员还能非常自然轻松的使用 Null Object Pattern 模式去处理 Null 问题。Optional 是非常值得在项目中大范围使用的。

烦人的Null,你可以走开点了

 

5. 总结

最后总结一下。

我们在项目中综合利用 @NonNull 注解,findbugs 静态代码检查,还有引入 Optional 等方式,大大减少了 NPE 出现的场合。

不过,有一说一,这些方法也会加大项目开发复杂度,增大了编译测试时间。

同时,使用好 findbugs 也是有一些门槛的,其本身检测代码有时候严格程度也很难把握。Optional本身也提供了 of 方法,这个方法不小心也会引入新的 NPE 问题。

但是,我认为这些相对于 NPE 可能对线上系统造成的损失而言,都是值得的。我们现在可以说:
NPE,你可以走开点了。

Kettle 运用中报错 1.修改kettle配置文件/home/hadoopap/data-integration/system/karaf/system/pentaho-karaf-features/pentaho-big-data-plugin-osgi/8.0.0.0-28/pentaho-big-data-plugin-osgi-8.0.0.0-28-features.xml。kettle JOB 假死,需要到系统上面杀死进程。报错信息: JOB一直处理执行状态。 阅读详情

相关推荐

.NET 处理 WebAPI JSON 返回烦人的null为空

前台对应字段赋值需要做null值判断,怎么才能全局把null替换为空。

DotNet技术匠 1652

thymeleaf 判断字符串 null 空串

包ez包j

顶顶顶顶顶顶顶顶顶顶顶顶 5333

迅雷下载接口java实现

根据迅雷提供的动态链接库和C++开放接口和使用实例,用java实现迅雷动态链接库的调用。

烦人的NULL,你可以走开点了

假设现在有一个需要三个参数的方法。其中第一个参数是必须的,后两个参数是可有可无的。第一种情况,在我们调用这个方法的时候,我们只能传入两个参数,对第三个参数,我们在上下文里是没有的,那么我们调用方法的时候,就需要用一个特殊值去告知这个方法: 第三个参数我们拿不到,参数是不存在或者不明确的。 这个特殊的值应该用什么呢?在 Java 中,我们会选择用 null 去表示这种情况。第二种情况,如果在调用方法的时候,我们有三个参数,只是第三个参数没有值,我们也需要传入一个特殊的值去表示: 参数存在,但是没有值。 这个特

JavaMonsterr的博客 190

量子密钥分发(QKD)原理、工程实现与实战部署全解析

密钥分发是信息安全的核心基础,它解决了通信双方如何安全共享秘密密钥的难题。传统方法依赖于数学问题的计算复杂性,而量子密钥分发(QKD)则基于量子力学原理,为密钥分发提供了信息论安全的物理保障。其核心价值在于,利用量子不可克隆定理和测量坍缩原理,使得任何窃听行为都会被合法通信方检测到,从而在理论上实现无条件安全的密钥协商。这项技术特别适用于对安全性要求极高的场景,如金融数据同步、政务专网和电力系统保护。本文聚焦于量子保密通信,深入剖析了以BB84协议为代表的QKD工作原理,并详细拆解了包含单光子探测、偏振编码

weixin_29324401的博客 350

从零到一:手把手教你用Verilog实现一个AHB-Lite总线主机(附完整代码)

本文详细介绍了如何使用Verilog从零开始实现一个AHB-Lite总线主机,涵盖协议解析、状态机设计、突发传输处理等关键环节,并提供完整代码示例。通过实战指南,帮助数字IC设计工程师掌握AMBA3.0总线协议的核心实现技术,提升SoC设计能力。

weixin_29209825的博客 363

超烦人的Null,你可以走开点了~

1. Null 的问题假设现在有一个需要三个参数的方法。其中第一个参数是必须的,后两个参数是可有可无的。第一种情况,在我们调用这个方法的时候,我们只能传入两个参数,对第三个参数,我们...

程序IT圈 161

【yolo】YOLOv8模型导出完全指南:从PT到ONNX及其他格式的完整实践

摘要:本文全面介绍了YOLOv8模型从PT格式导出为ONNX等部署格式的完整流程与最佳实践。重点解析了关键参数(如format、imgsz、simplify)的作用机制,特别强调输入尺寸imgsz会自动继承训练尺寸的特性,并提供了ONNX、TensorRT等格式的典型导出配置方案。文章还总结了常见问题解决办法,推荐使用simplify优化模型性能,同时分享了通过C#实现模型重命名的实用技巧。最后指出"训练决定能力,导出定义接口"的核心原则,帮助开发者高效完成模型部署转换。

songhuangong123的博客 1917

thymeleaf 因为值空null 界面500_烦人的NULL,你可以走开点了

1. Null 的问题假设现在有一个需要三个参数的方法。其中第一个参数是必须的,后两个参数是可有可无的。第一种情况,在我们调用这个方法的时候,我们只能传入两个参数,对第三个参数,我们在上下文里是没有的,那么我们调用方法的时候,就需要用一个特殊值去告知这个方法:第三个参数我们拿不到,参数是不存在或者不明确的。这个特殊的值应该用什么呢?在 Java 中,我们会选择用 null 去表示这种情况。第二种情...

weixin_39737947的博客 927

如何分段长tree

可以将clock1 tree上所有的cell don’t touch,update一下sdc,将clock2的信息load进来。那么,此时只要将clock1的定义去除,用delete_ccopt_clock_tree_spec将原先已经load的spec删除,然后再次创建clock tree spec,那么此时工具只会生成clock2的spec。cts之后,工具便会生成只有clock2的clock tree。那么,作为思考题,童鞋们可以试试看如何才能实现在mux I0之前长1ns的clock tree。

芯冰乐 503

【异常】安装hermes-agent时提示GnuTLS recv error (-110): The TLS connection was non-properly terminated.

Git克隆仓库时出现TLS连接异常报错的解决方案摘要: 当执行git clone命令时遇到"GnuTLS recv error (-110)"报错,通常由网络不稳定、缓冲区不足或证书验证问题导致。主要解决方案包括:1)增大Git HTTP缓冲区(git config --global http.postBuffer 524288000);2)使用GitHub镜像站加速克隆;3)临时禁用SSL验证进行测试;4)检查并调整代理配置;5)改用SSH协议克隆。建议优先尝试增大缓冲区和镜像站方案,

奶爸的编程之路,也就一周冷个三天 1352

thymeleaf 因为值空null 界面500_烦人的Null,你可以走开点了

来源:四猿外(ID:si-yuanwai)作者:四猿外1. Null 的问题假设现在有一个需要三个参数的方法。其中第一个参数是必须的,后两个参数是可有可无的。第一种情况,在我们调用这个方法的时候,我们只能传入两个参数,对第三个参数,我们在上下文里是没有的,那么我们调用方法的时候,就需要用一个特殊值去告知这个方法:第三个参数我们拿不到,参数是不存在或者不明确的。这个特殊的值应该用什么呢?在...

weixin_39902345的博客 513

【WRF-Chem工具】pyVPRM 计算大气与陆地植被之间的 CO₂ 交换通量

pyVPRM 计算大气与陆地植被之间的 CO₂ 交换通量

WW、forever的博客 210

Java运行报NPE错误_烦人的Null,你可以走开点了

作者 | 四猿外出品 | 四猿外(ID:si-yuanwai)头图 | 优快云 下载自视觉中国Null 的问题假设现在有一个需要三个参数的方法。其中第一个参数是必须的,后两个参数是可有可无的。第一种情况,在我们调用这个方法的时候,我们只能传入两个参数,对第三个参数,我们在上下文里是没有的,那么我们调用方法的时候,就需要用一个特殊值去告知这个方法:第三个参数我们拿不到,参数是不存在或者不明确的。...

weixin_29082143的博客 945

第十届MathorCup高校数学建模挑战赛-B题:养老服务床位需求预测与运营模式研究

当养老床位数增加时存在的商机,提出了相应的养老服务床位的运营商业模式。就业的可能性,建立多目标规划模型,尽可能同时满足三方面的要求。务床位的需求、制定合理的养老服务床位发展规划,是构建和谐社会、幸福社会。问题一的床位需求与市场类型的分类结果,查找关于国内养老院的相关数据,探。求,又能持续发展养老事业,同时还能促进社会就业的养老服务床位运营的商业。养老服务床位数的增加能够带来的就业方面因素的影响,并对这些因素进行一个。你们的模型及其结论为科学依据,对政府管理部门针对养老床位规划提出合理的。

getusushu的博客 1140

产品路线图的三种模型(RICE/MoSCoW/Kano),教你如何对需求进行优先级排序

RICE/MoSCoW/Kano三种模型,教你如何对需求进行优先级排序。 也许你会让业务提供一份ROI,记得前不久参加过一场立项会评审,一位很有意思的小产品在会上讲不清楚ROI,评审们要求会后重新梳理,小产品表达不要为难业务方干一些他们不擅长的事了。这个看似笑话的经历,背后隐藏着价值判断已经流于形式。 也许你会要求业务方直接给出需求优先级列表,把任务分为P0到P5,这样的划分除了按需求本质的优先级还同时考虑了开发资源、开发难度等问题。毫不夸张地说,我曾经拿到一张全是P0级别的需求清单,如果一切任务都是高

wenyusuran的专栏 5547

kettle执行ktr文件时无法将null值插入_烦人的Null,你可以走开点了

1. Null 的问题假设现在有一个需要三个参数的方法。其中第一个参数是必须的,后两个参数是可有可无的。第一种情况,在我们调用这个方法的时候,我们只能传入两个参数,对第三个参数,我们在上下文里是没有的,那么我们调用方法的时候,就需要用一个特殊值去告知这个方法:第三个参数我们拿不到,参数是不存在或者不明确的。 这个特殊的值应该用什么呢?在 Java 中,我们会选择用 null 去表示这种情况。第二种...

weixin_30227789的博客 1575

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

ibatis的sqlmap.xml中id可以传入一个参数_超烦人的Null,你可以走开点了~

1. Null 的问题假设现在有一个需要三个参数的方法。其中第一个参数是必须的,后两个参数是可有可无的。第一种情况,在我们调用这个方法的时候,我们只能传入两个参数,对第三个参数,我们在上下文里是没有的,那么我们调用方法的时候,就需要用一个特殊值去告知这个方法:第三个参数我们拿不到,参数是不存在或者不明确的。这个特殊的值应该用什么呢?在 Java 中,我们会选择用 null 去表示这种...

weixin_39977934的博客 195

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

ibatis的sqlmap.xml中id可以传入一个参数_烦人的Null,你可以走开点了

关注“脚本之家”,与百万开发者在一起作者|四猿外出品|四猿外(ID:si-yuanwai)Null 的问题假设现在有一个需要三个参数的方法。其中第一个参数是必须的,后两个参数是可有可无的。第一种情况,在我们调用这个方法的时候,我们只能传入两个参数,对第三个参数,我们在上下文里是没有的,那么我们调用方法的时候,就需要用一个特殊值去告知这个方法:第三个参数我们拿不到,参数是不存在或...

weixin_39603050的博客 104

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

手把手教你如何处理烦人的NULL值

<h2 id="在日常使用数据库时,你在意过null么?">在日常使用数据库时,你在意过NULL么?</h2> <p>其实,NULL值在数据库中是一个很特殊且<strong>有趣</strong>的存

码工是小希 2789

干掉烦人的 Null !

1. Null 的问题假设现在有一个需要三个参数的方法。其中第一个参数是必须的,后两个参数是可有可无的。第一种情况,在我们调用这个方法的时候,我们只能传入两个参数,对第三个参数,我们在上...

WantFlyDaCheng的博客 146

赋值为null_C#中烦人的Null值判断竟然这样就被消灭了

作者:依乐祝首发自:DotNetCore实战 公众号https://www.cnblogs.com/yilezhu/p/14177595.htmlNull值检查应该算是开发中最常见且烦人的工作了吧,有人反对吗?反对的话请右上角关门不送。这篇文章就教大家一招来简化这个烦人又不可避免的工作。罗嗦话不多说,先看下面一段简单的不能再简单的null值判断代码:public void DoSomet...

weixin_30913041的博客 684

C#中烦人的Null值判断竟然这样就被消灭了

作者:依乐祝 首发自:DotNetCore实战 公众号https://www.cnblogs.com/yilezhu/p/14177595.html Null值检查应该算是开发中最常见且烦人的工作了吧,有人反对吗?反对的话请右上角关门不送。这篇文章就教大家一招来简化这个烦人又不可避免的工作。 说明,提供思路的一篇文章招来这么多非议,为何啊? 罗嗦话不多说,先看下面一段简单的不能再...

依乐祝的博客 731
上一篇: Redis+NodeJS实现能处理海量数据的异步任务队列系统
下一篇: 惊艳!阿里出产的MyCat性能笔记,带你领略什么叫细节爆炸
爱玛士
博客等级 码龄7年 720粉丝 253原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值