Android studio 防止Android Studio Inspection将Java流链标记为包含可能的NullPointerException

Android studio 防止Android Studio Inspection将Java流链标记为包含可能的NullPointerException,android-studio,intellij-idea,nullpointerexception,java-stream,intellij-inspections,Android Studio,Intellij Idea,Nullpointerexception,Java Stream,Intellij Inspections,我正在编写一个实用方法来提取包装的不可分割对象数组: 公共接口不可拆分持有者{ @可为null的U getUnparcelable(); } 公共最终类FragmentUtil{ @可空 公共静态列表GetUnparableHolderListArgument( @非空片段片段, @非Null类unparcelableHolderClass, @非空字符串键 ) { @可为null的最终束参数=fragment.getArguments(); if(参数==null){ 返回null; }否则{

我正在编写一个实用方法来提取包装的不可分割对象数组:

公共接口不可拆分持有者{
@可为null的U getUnparcelable();
}
公共最终类FragmentUtil{
@可空
公共静态列表GetUnparableHolderListArgument(
@非空片段片段,
@非Null类unparcelableHolderClass,
@非空字符串键
) {
@可为null的最终束参数=fragment.getArguments();
if(参数==null){
返回null;
}否则{
@可为空的最终Parcelable[]parcelableArray=参数。getParcelableArray(键);
如果(parcelableArray==null){
返回null;
}否则{
返回数组
.溪流(地块阵列)
.filter(unparcelableHolderClass::isInstance)
.map(unparcelableHolderClass::cast)
.filter(对象::非空)
.map(UnparcelableHolder::getUnparcelable)
.filter(对象::非空)
.collect(Collectors.toList());
}
if(不可拆分的持有者类别isInstance(可打包)){
@非Null最终不可拆分持有者不可拆分持有者=
对象.requirennoull(不可拆分的持有者类.cast(可打包));
返回unparcelableHolder.getUnparcelable();
}否则{
返回null;
}
}
}
}
Android Studio警告我,我的
.map(UnparcelableHolder::getUnparcelable)
调用可能导致
NullPointerException
。这应该是不可能的,因为我前面的
过滤器(Objects::nonNull)
调用。我如何告诉Android Studio的检查员我的代码是干净的

这是安卓Studio 3.4 beta 2的内置版本:

build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.github.hborders.streamsnonnulljsr305"
        minSdkVersion 28
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility = '1.8'
        targetCompatibility = '1.8'
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.google.code.findbugs:jsr305:3.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
MainActivity.java

package com.github.hborders.streamsnonnulljsr305;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public class MainActivity extends AppCompatActivity {

    class Foo {
        @Nonnull
        private final String string;

        Foo(@Nonnull String string) {
            this.string = string;
        }

        @Nonnull
        String getString() {
            return string;
        }
    }

    class Bar {
        @Nullable
        private final Foo foo;

        Bar(@Nullable Foo foo) {
            this.foo = foo;
        }

        @Nullable
        Foo getFoo() {
            return foo;
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final Bar bar1 = new Bar(new Foo("foo"));
        final Bar bar2 = new Bar(null);
        final Bar[] bars = new Bar[]{
                null,
                bar1,
                bar2,
        };
        final List<String> strings = Arrays
                .stream(bars)
                .map(Bar::getFoo)
                .filter(Objects::nonNull)
                .map(Foo::getString)
                .collect(Collectors.toList());
        System.out.println("strings: " + strings);

    }
}
package com.github.hborders.streamsnoulljsr305;
导入android.support.v7.app.AppActivity;
导入android.os.Bundle;
导入java.util.array;
导入java.util.List;
导入java.util.Objects;
导入java.util.stream.collector;
导入javax.annotation.Nonnull;
导入javax.annotation.Nullable;
公共类MainActivity扩展了AppCompatActivity{
福班{
@非空
私有最终字符串;
Foo(@Nonnull字符串){
this.string=string;
}
@非空
字符串getString(){
返回字符串;
}
}
分类栏{
@可空
私人决赛福福;
条(@Nullable Foo Foo){
this.foo=foo;
}
@可空
Foo getFoo(){
返回foo;
}
}
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
最终条形图1=新条形图(新Foo(“Foo”));
最终棒2=新棒(空);
最终钢筋[]钢筋=新钢筋[]{
无效的
bar1,
bar2,
};
最终列表字符串=数组
.溪流(巴)
.map(Bar::getFoo)
.filter(对象::非空)
.map(Foo::getString)
.collect(Collectors.toList());
System.out.println(“字符串:“+strings”);
}
}

同样的问题也发生在
.map(Foo::getString)
调用上。具有讽刺意味的是,Android studio并没有抱怨我的
.map(Bar::getFoo)
调用,尽管它确实抛出了一个
NullPointerException

这是Android studio的一个bug,因为Android studio的建议在这里都不起作用

没有警告:

应用建议并获得警告:

它还建议插入
.filter(Objects::nonNull)
步骤(如果已经存在)

所以这是一个明确的错误

这是本期真正的MCVE:

import android.support.annotation.Nullable; // or any nullable you care to use

import java.util.Arrays;
import java.util.Objects;

public class MCVE {

    class Foo {
    }

    class Bar {
        @Nullable
        private final Foo foo;

        Bar(@Nullable Foo foo) {
            this.foo = foo;
        }

        @Nullable
        Foo getFoo() {
            return foo;
        }
    }

    public void mcve() {
        final Bar[] bars = new Bar[]{
                new Bar(new Foo()),
        };
        Arrays.stream(bars)
                .map(Bar::getFoo)
                .filter(Objects::nonNull)
                .map(Foo::toString);
    }
}

getUnparcelable()
的签名是什么?我在上面的代码片段中声明了它,但我刚刚注意到我在转录它时把可空性搞错了。我编辑了这篇文章。这是签名:
public interface unparcelable holder{@Nullable U getUnparcelable();}
我不确定它是否抱怨
getUnparcelable()
null
对象上被调用,或者
getUnparcelable()
可能返回
null
对象。尝试将签名临时更改为
@NotNull U getUnparcelable()并查看林特警告是否更改。如果是,则它会抱怨
getUnparcelable()
的返回值。如果没有,那么您可能只是遇到了Lint限制,因为它无法知道在您的情况下,
filter()
恰好返回了非
null
对象。我认为它在抱怨
getUnparbelable()
null
上被调用,因为
.map(UnparcellabelHolderClass::cast)
也可以返回
null
,它不会对此抱怨。在什么地方可以提交此错误?