Attempt to invoke virtual method ‘…’ on a null object reference

Attempt to invoke virtual method ‘…’ on a null object reference尝试在空对象引用上调用…虚拟方法

遇到了四次这样的提示,逐个解析之。

一、只声明,未创建。

如下代码:

public class SortMallFragment extends Fragment {
    ... ...
    private ArrayList<Fragment> rightFragments; 
    
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        //rightFragments = new ArrayList<>();
        for (int i = 0; i < leftTitles.length; i++){      
        rightFragments.add(RightSortMallFragment.newInstance(leftTitles[i],"0"));
        }
     ... ...
    }
}

错误提示为:Attempt to invoke virtual method ‘boolean java.util.ArrayList.add(java.lang.Object)’ on a null object reference,即:尝试在空对象引用上调用虚拟方法“boolean java.util.ArrayList.add(java.lang.Object)”。
主要原因对象rightFragments只声明,未创建,是空的(null),当调用其add()方法时,就不符合逻辑了。改正方法就是将上述代码中的双斜杠去掉,即创建一下对象就可以了。

二、循环过程中无法生成对象。

如下代码:

        for (int i = 0; i<5; i++){
            LinearLayout v0 = (LinearLayout) tabLayout.getChildAt(i); 
            LinearLayout v1 = (LinearLayout) v0.getChildAt(0);                                
                ... ...  
        }

若tabLayout中只有2个子项,而循环要进行5轮。等循环到第3轮时,v0就是一个空对象,调用其getChildAt()方法,试图从里面拿出些什么,恐怕什么也拿不出来,所以报错:
Attempt to invoke virtual method ‘android.view.View android.view.ViewGroup.getChildAt(int)’ on a null object reference
这时虽然语法不错,但逻辑肯定有问题,应朝这个方向寻找问题。

三、HashMap中本无目标对象,却“强行”取出,还马上使用。

如下代码:

public class SkyPlatform {
    public static HashMap<Integer, BuyInfoSortMall> tempInfoSortMall = new HashMap<>();
}
 ......
    // tempInfoSortMall是SkyPlatform类中的HashMap对象
    // bism是“存储类”BuyInfoSortMall
    BuyInfoSortMall bism = SkyPlatform.tempInfoSortMall.get(id);
    //获取tempInfoSortMall中对应id对应类中的Quantity(数量)值
    int count = bism.getQuantity();
    ......

此时若tempInfoSortMall不存在id对应的类对象,取到的“假对象”bism的getQuantity()就会什么也得不到,就会报错。解决方法就是之前做一下bism是否为空的判断,并作不同处理。

四、调用了“空的”上下文(Context)

代码如下:

public static void displayDirctory() {
        String mDataRootPath = Environment.getExternalStorageDirectory().
                getPath(); // 获取公共外部存储路径字符串
        Log.d("公共外部存储路径”:",mDataRootPath);
        String mDataRootPath1 = context.getExternalFilesDir("").
                getAbsolutePath(); // 获取私有外部存储路径字符串
        Log.d("私有外部存储路径”:",mDataRootPath1);
}

代码中的context没有被“充实”,是空的,调用其方法时必然产生错误。

解决方法1:
重写自己的Application类:MyApplication继承自Application类,在其中构造一个全局Context,其它地方使用时调用即可:

public class MyApplication extends Application {
    public static Context context;
    @Override
    public void onCreate() {
        super.onCreate();
        context = getApplicationContext();
    }

    public static Context getContext() {
        return context;
    }
}

调用:

String mDataRootPath1 = MyApplication.getContext().getExternalFilesDir("").
                getAbsolutePath();

同时在AndroidManifest的application标签下进行指定就可以了:

<application
        android:name="com.example.test.util.MyApplication"

这种方法通用性强,一次书写,到处调用,但全局Context,可能体量会大一些吧。

解决方法2
写方法时加入参数Context,在“活动”中调用时配给参数(this或其它Context参数)。
方法代码:

public  class FilesUtils {
    public static void displayDirctory(Context context) {
        String mDataRootPath = Environment.getExternalStorageDirectory().
                getPath(); // 此路径:
        Log.d("公共外部存储路径”:",mDataRootPath);
        String mDataRootPath1 = context.getExternalFilesDir("").
                getAbsolutePath(); // 此路径:
        Log.d("私有外部存储路径”:",mDataRootPath1);
    }
}

调用代码:

public class MainActivity extends AppCompatActivity {
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        String FilesUtils.displayDirctory(this);
        ...
    }
}

解决方法3:
直接使用“this”。代码写在“Activity”中,需要上下文处写上“this.”,代码:

public class MainActivity extends AppCompatActivity {
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        String mDataRootPath1 = this.getExternalFilesDir("").
                getAbsolutePath();
        ...
    }
}

此方法简单,但在复杂的调用中,显得不太好使了。

其它方法有待研究。

五、小结

出现“Attempt to invoke virtual method ‘…’ on a null object reference”提示,首先说明有一个空对象,其次还要调用这个对象的方法,代码形如:“空对象.方法()”。这好比还没发工资,就拿着“钱影子”去买东西,逻辑上很荒谬。解决的方向应该是仔细研究这个“空对象”的由来。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值