精华内容
下载资源
问答
  • 今天来总结下 nullable, nonnull, __nullable, __nonnull, _Nullable, __Nonnull 之间的区别。 作用 首先, nonnull, __nonnull, __Nonnull 这三个修饰的参数是不可以为nil的。如果参数被它们修饰, 且传入的实参....

    在苹果自己的API中, 我们也见过许多的参数的修饰符, 比如说在方法中修饰参数可否为空的标识。今天来总结下 nullable, nonnull, __nullable, __nonnull, _Nullable, __Nonnull 之间的区别。

    作用

    首先, nonnull, __nonnull, __Nonnull 这三个修饰的参数是不可以为nil的。如果参数被它们修饰, 且传入的实参为nil的话, 编译器将会产生警告。
    nullable, __nullable, _Nullable 这三个修饰的参数是可以为nil的。如果参数被它们修饰, 且传入的实参为nil的话, 编译器也不会产生警告。

    用法

    // string 可以为 nil
    - (void)methodWithString:(nullable NSString *)string {}
    // string 不可以为 nil
    - (void)methodWithString:(nonnull NSString *)string {}
    

    nullable__nullable_Nullable 的区别联系

    nullable__nullable_Nullablenonnull__nonnull__Nonnull 其实是成对的, 所以这里只介绍前者, 后者用法与前者一致。

    先来看一段代码, 可以考虑下它们之间的区别是什么。

    @property (nonatomic, copy, nullable) NSString *string1;
    @property (nonatomic, copy) NSString * _Nullable string2;
    @property (nonatomic, copy) NSString * __nullable string3;
    
    - (void)methodWithString1:(nullable NSString *)string {}
    - (void)methodWithString2:(NSString * _Nullable)string {}
    - (void)methodWithString3:(NSString * __nullable)string {}
    

    其实呢, 这三种写法的效果都是一样的,只是代码摆放的位置不同。
    苹果在 Xcode 6.3 引入了一个 Objective-C 的新特性: Nullability Annotations ,它的核心是两个修饰: __nullable__nonnull 。在 Xcode 7 中,为了避免与第三方库潜在的冲突,苹果把 __nonnull__nullable 改成 _Nonnull_Nullable 。而且苹果也支持没有下划线的写法 nonnullnullable ,于是就三种写法都可以使用的情况。

    从上面的代码可以看出, nullable 修饰于类型前, 但__nullable_Nullable 却修饰于类型后。

    那么它们还有其他的区别呢?
    对于方法参数、方法返回值、属性的修饰,可以使用:nonnullnullable 或者 _Nonnull_Nullable 或者 __nonnull__nullable
    对于 C函数的参数、Block的参数、Block返回值的修饰,只能使用: _Nonnull_Nullable 或者 __nonnull__nullable 。但是根据苹果的API来说建议弃用__nonnull__nullable

    所以应该按照下面的代码来写:

    // C函数
    - (void)methodWithError1:(NSError * _Nullable * _Nullable)error {}
    // Block 返回值
    - (void)methodWithBlock1:(void(^ _Nullable)(void))block {}
    - (void)methodWithBlock2:(void(^ __nullable)(void))block {}
    // 注意下面的 nullable 用于修饰传入的参数 block 可以为空,而不是修饰 block 返回值
    - (void)methodWithBlock3:(nullable void(^)(void))block {}
    
    // Block返回值 和 Block参数
    - (void)methodWithBlock4:(NSString * __nonnull(^ __nullable)(NSString * __nullable params))block {}
    - (void)methodWithBlock5:(NSString * _Nonnull (^ _Nullable)(NSString * _Nullable params))block {}
    // 注意下面的 nullable 用于修饰方法传入的参数 block 可以为空,而 __nonnull 用于修饰 block 返回值 NSString 不能为空;
    - (void)methodWithBlock6:(nullable NSString * __nonnull(^)(NSString * __nullable params))block {}
    

    拓展 Nonnull Audited Regions

    有两个宏 NS_ASSUME_NONNULL_BEGINNS_ASSUME_NONNULL_END 。在这两个宏之间的代码,所有简单指针对象都被认为是 nonnull 修饰的 ,所以我们只需要指定 nullable 的指针对象即可。

    NS_ASSUME_NONNULL_BEGIN
    
    - (void)methodWithString4:(NSString *)str string:(nullable NSString *)string {}
    
    NS_ASSUME_NONNULL_END
    

    如上写的话, 参数strnonnull的, 而参数stringnullable 的。

    总结

    对于方法参数、方法返回值、属性的修饰,可以使用:nonnullnullable 或者 _Nonnull_Nullable 或者 __nonnull__nullable
    对于 C函数的参数、Block的参数、Block返回值的修饰,只能使用: _Nonnull_Nullable 或者 __nonnull__nullable 。但是根据苹果的API来说建议弃用__nonnull__nullable

    Demo下载地址:
    Demo
    参考资料:
    Difference between nullable, __nullable and _Nullable in Objective-C

    展开全文
  • What is the best 'NonNull' annotation?"Best" in the sense ofStandard way e.g. future proofness (e.g. support by standard jdk etc.)Support of IDE's (shows up in java doc to indicate the usage for devel...

    What is the best 'NonNull' annotation?

    "Best" in the sense of

    Standard way e.g. future proofness (e.g. support by standard jdk etc.)

    Support of IDE's (shows up in java doc to indicate the usage for developers)

    Support by static analysis tools like findbugs

    Support for runtime analysis

    Here's how the world currently look like - any further insight is appreciated:

    javax.validation.constraints.NotNull (Docs)

    + javax package thus seems futureproof

    - Part of JEE not JSE. In JSE need to import additional libs.

    - Not supported by static analysis tools (runtime validation only)

    edu.umd.cs.findbugs.annotations.NonNull (docs)

    - external library and not an javax package

    - deprecated since findbugs version 3.X

    + used for static analysis (by findbugs and therefore Sonar)

    javax.annotation.Nonnull (docs)

    + used for static analysis (in findbugs)

    - JSR-305 is dormant/dead/unknown as on the fb mailing list indicated. The author Bill Pugh, even if directly asked, hasn't commented the state in years...

    org.eclipse.jdt.annotation_2.0.0 (docs, interesting presentation)

    + used for static analysis (in eclipse not in findbugs though)

    - proprietary to eclipse (didn't try to use them standalone)

    org.jetbrains.annotations.NotNull (docs)

    + used for static analysis (in intelliJ not in findbugs though)

    - proprietary to IntelliJ (but also publicly available as a jar)

    lombok.NonNull(docs)

    + used to control code generation

    - proprietary annotation

    android.support.annotation.NonNull (docs)

    + static analysis in android studio

    - android specific proprietary annotation

    org.checkerframework.checker.nullness.qual.NonNull (docs)

    + JSR308 implementation which is part of Java8 (which did introduce the ability to write annotations in different parts of your code, but did not introduce new annotations)

    + used for static code (not findbugs though) and runtime analysis

    - external lib however seems to be endorsed by the java folks

    Currently I would tend to the Checker Framework but I am looking forward for other views...

    [disclaimer] I know the question has been asked here however was not answered (or the answer was wrong/incomplete/outdated)

    [/disclaimer]

    解决方案

    There is no standard @NonNull annotation. Creating such an annotation was the goal of JSR 305, which has been abandoned for a long time. There will not be a standard @NonNull annotation until JSR 305 is reconstituted. Oracle has no current plans to do so. (JEE annotations are outside the scope of JSR 305.)

    For futureproofing, I think the most important factor to consider is whether the annotation is a type annotation or a declaration annotation. Because @NonNull states a property of the variable's value rather than of the variable itself, it should be a type annotation. Being a type annotation also lets the annotation be written on more locations, as in List.

    You can determine whether an annotation is a type annotation by looking at the @Target meta-annotation on the annotation's definition. It seems that only the Checker Framework and Eclipse versions are type annotation, so I would choose them over the ones that are declaration annotations. Note that the developers of any of the other annotations could update them to be type annotations as well; I don't know of their plans.

    The only downside is that using a type annotation requires use of a Java 8 compiler. The Checker Framework has mechanisms for letting code containing its annotations be compiled by a Java 7 compiler.

    展开全文
  • Lombok之@NonNull使用

    千次阅读 2019-10-15 15:06:48
    为什么要用@NonNull?二. @NonNull如何使用?三. @NonNull源码四. 特别说明 一. 为什么要用@NonNull? 二. @NonNull如何使用? 三. @NonNull源码 四. 特别说明 本文已经收录在Lombok注解系列文章总览中,并继承上文中...

    一. 为什么要用@NonNull?

    NullPointerException空指针异常(俗称NPE异常)可以说是每一个开发者都遇到过的一个常见异常,即使是经验丰富的老手,也会在一不留神的写出NPE的bug。指针只存在于c语言中,Java中是没有指针的,空指针就是空引用,java空指针异常就是引用本身为空,却调用了方法,这个时候就会出现空指针异常。可以理解,成员变量和方法是属于对象的(除去静态),在对象中才存在相对应的成员变量和方法,然后通过对象去调用这些成员变量和方法。对于空指针来说,它不指向任何对象,也就没有所谓的成员变量和方法,这个时候用它去调用某些属性和方法,当然会出现空指针异常。
    新建Student类,并创建全参构造函数,getter和setter方法。

    public class Student {
    
        private String name;
    
        private Integer age;
    
        public Student(String name, Integer age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    }
    

    示例代码
    我们new了一个name为null,age为18的student对象。可以看到当程序通过student.getName()访问name变量后,再调用String的实例方法length(),控制台抛出了NullPointerException异常。这是因为name的变量值为null,所以报NPE异常。解决这类问题的办法,我们可以在取出name值后进行判空操作,但是这样每次取name值都要进行判空操作,很是麻烦。我们可以在构造函数中要求name值非空:

       public Student(String name, Integer age) {
            if (name == null) {
                throw new NullPointerException("name is null");
            } else {
                this.name = name;
                this.age = age;
            }
        }
    

    这样一来,我们在new的时候就会提前发现错误。new的时候就会报NullPointerException,避免后面的空指针异常。new时候的空指针异常是不可能避免的,这是由于Java中规定null可以为任何包装类型的变量赋值。这个判空的逻辑体可以使用Lombok的注解@NonNull进行简化代码。

    二. @NonNull如何使用?

    在个构造函数的参数加上@NonNull后,便会自动对该参数值进行判空。

     public Student(@NonNull String name, Integer age) {
            this.name = name;
            this.age = age;
        }
    

    编译该工程,打开编译后的文件。可以看到,编译器已经为形参name生成了判空的代码。
    student.class

    三. @NonNull源码

    package lombok;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * If put on a parameter, lombok will insert a null-check at the start of the method / constructor's body, throwing a
     * {@code NullPointerException} with the parameter's name as message. If put on a field, any generated method assigning
     * a value to this field will also produce these null-checks.
     * 如果放在一个参数上,lombok将在方法/构造函数体的开头插入一个空检查,抛出一个{@code NullPointerException},参数名为message。如果放
     * 在字段(成员变量)上,则生成的任何方法都被赋值该字段的值也将产生这些空值检查。
     */
    @Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.TYPE_USE})
    @Retention(RetentionPolicy.CLASS)
    @Documented
    public @interface NonNull {
    }
    
    

    四. 特别说明

    本文已经收录在Lombok注解系列文章总览中,并继承上文中所提的特别说明。
    源码地址:gitee

    展开全文
  • nonnull和nullable

    2018-03-14 14:36:12
    1,nonnull和nullable声明属性是否可以为nil,如果对nonnull属性赋值为nil,则会报警告。123@property (nonatomic, strong, nonnull) NSArray *array1;@property (nonatomic, strong) NSArray * __nullable array2;...
    1,nonnull和nullable
    声明属性是否可以为nil,如果对nonnull属性赋值为nil,则会报警告。
    1
    2
    3
    @property (nonatomic, strong, nonnull) NSArray *array1;

    @property (nonatomic, strong) NSArray * __nullable array2;
    作用主要是开发者之间交互,调用属性时可以知道这个属性是可能为nil的,针对这个状态做些处理。
    默认情况下就是nullable状态。
    可以用来给方法的参数最要求,比如定一个方法,参数为一个不为空的对象:
     
    2,null_resettable
    声明属性set方法可以为nil,但是get一定不能为nil,这里有一个貌似冲突的地方,就是可以定义个属性为nil,但是在获取这个属性的时候,这个属性不能为nil,否则会有警告。
     
    这里用到的地方例如在UIViewController中的view,意味着开发者可以对控制器的view清空赋值为nil,但是控制器view是懒加载的,每次获取控制器的view时候,都可以再获取到非nil的view。
     
    一个Objective-C的新特性:nullability annotations。这一新特性的核心是两个新的类型注释:__nullable__nonnull从字面上我们可以猜到,__nullable表示对象可以是NULL或nil,而__nonnull表示对象不应该为空。当我们不遵循这一规则时,编译器就会给出警告。
    不过这只是一个警告,程序还是能编译通过并运行。
    事实上,在任何可以使用const关键字的地方都可以使用__nullable和__nonnull,不过这两个关键字仅限于使用在指针类型上。而在方法的声明中,我们还可以使用不带下划线的nullable和nonnull
    展开全文
  • @NonNull 说到NullPointerException,可能会是所有java搬砖工的噩梦吧? 现在有了@NonNull , 让我们不在忧虑NPE!!! 您可以在方法或构造函数的参数上使用@NonNull让lombok为您生成null-check语句。 如果lombok为...
  • Objective-C为了和Swift兼容,每个属性或每个...苹果为了减轻我们的工作量,定义了NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END两个宏。 在这两个宏之间的所有简单指针对象都被假定为nonnull。我们只需要指定...
  • NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END 作用 这两个东西是Nonnull区域设置(Audited Regions) 。 这两个宏之间的代码里的所有简单指针对象都被默认为 ___nonnull,我们只需要去指定 __nullable 的指针。 ...
  • NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END

    千次阅读 2016-08-18 16:38:34
    NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END
  • 我正在开发一个Android应用程序请帮...import android.support.annotation.NonNull;import android.support.annotation.Nullable;我添加了以下依赖项:dependencies {compile group: 'com.google.code.findbugs',na...
  • 浅谈Spring之@Nullable、@NonNull注解

    万次阅读 热门讨论 2019-02-16 23:44:28
    @NonNull可以标注在方法、字段、参数之上,表示对应的值不可以为空 @Nullable注解可以标注在方法、字段、参数之上,表示对应的值可以为空 以上两个注解在程序运行的过程中不会起任何作用,只会在IDE、编译器、...
  • Lombok @NonNull注解

    2021-01-27 13:57:55
    概述 普通的 POJO 需要写或是用IDEA等集成开发环境生成大量gettter, setter方法 普通的 POJO 对于 equals 和 hashCode 等...@NonNull注解用来判断项目中的字段是否为空,为空抛出异常 public class NonNullAnnotation {
  • Nonnull区域设置(Audited Regions) 如果需要每个属性或每个方法都去指定nonnull和nullable,是一件非常繁琐的事。苹果为了减轻我们的工作量,专门提供了两个宏:NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END...
  • Android 关于@NonNull

    万次阅读 2015-10-22 19:19:49
    本文介绍Android 代码编写过程中的一个注释@NonNull的源码解释。
  • Nonnull区域设置(Audited Regions) 如果需要每个属性或每个方法都去指定nonnull和nullable,是一件非常繁琐的事。苹果为了减轻我们的工作量,专门提供了两个宏:NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END...
  • 升级成 Xcode 10 之后每次 New File 看到 .h 基本都能看到 NS_ASSUME_NONNULL_BEGIN 和 NS_ASSUME_NONNULL_END 成对出现在 @interface 与 @end 上下, 包裹住它, 这两对关键字并非新特性, 只是 Xcode 10 之后系统默.....
  • Nonnull区域设置(Audited Regions)  如果需要每个属性或每个方法都去指定nonnull和nullable,是一件非常繁琐的事。苹果为了减轻我们的工作量,专门提供了两个宏:NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END...
  • 最近使用新更新的Xcode10.0新建类时,发现它自动为我们在.h文件里添加了NS_ASSUME_NONNULL_BEGIN和 NS_ASSUME_NONNULL_END。如下示例: #import <UIKit/UIKit.h> NS_ASSUME_NONNULL_BEGIN @...
  • Nonnull区域设置(Audited Regions) 如果需要每个属性或每个方法都去指定nonnull和nullable,是一件非常繁琐的事。苹果为了减轻我们的工作量,专门提供了两个宏:NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END。 ...
  • __nullable和__nonnull是Xcode 6.3引入的新的关键字。 顾名思义,__nullable表示可以为nil,__nonnull则反之。 举例代码如下: @implementation ViewController - (void)...
  • import android.support.annotation.NonNull;报错

    万次阅读 多人点赞 2019-10-28 11:45:33
    将import android.support.annotation.NonNull;换成import androidx.annotation.NonNull;
  • 该项目为javax.annotation.Nonnull注释的方法参数实现了驱动的运行javax.annotation.Nonnull值检查。 在内部, @Before切入点用于拦截具有一个或多个@Nonnull注释参数的方法并检查它们的值是否为非空。 此功能由...
  • NS_ASSUME_NONNULL_BEGIN

    千次阅读 2018-08-30 14:48:02
    NS_ASSUME_NONNULL_BEGIN & NS_ASSUME_NONNULL_END 从表面意思来看,NS设定不可为空开始 & NS设定不可为空结束 苹果提供的两个宏,方便我们在定义属性的时候将不可为空的属性都写在 “NS设定不可...
  • Objects.nonNull(list.get(0))); // 2.但第二步这里报了空指针异常 QueryWrapper<SfCheckTask> queryWrapper = new QueryWrapper<>(); queryWrapper.ge(false && Objects.nonNull...
  • Android中Object.requireNonNull和@NonNull Android中的Object.requireNonNull和@NonNull并不能解决报错的问题,相反,是为了更快速的抛出问题、定位问题。 问题1: 不加上Object.requireNonNull也会抛出异常,为什么...
  • @NonNull 等资源注解

    万次阅读 2018-02-02 17:02:29
    1、@NonNull 告诉编译器,参数非空 2、@Nullable 告诉编译器 参数可为空 3、@IdRes 声明参数是个id 4、@StringRes 声明这个 int 参数是个字符串资源 5、@StyleRes 声明参数是个style 类型 6、LayoutRes 声明...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 78,752
精华内容 31,500
关键字:

nonnull