尝试在空对象引用上调用虚拟方法“void java.io.BufferedReader.close()”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33178708/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 14:25:19  来源:igfitidea点击:

Attempt to invoke virtual method 'void java.io.BufferedReader.close()' on a null object reference

javaandroid

提问by Nitish Chopra

Attempt to invoke virtual method 'void java.io.BufferedReader.close()' on a null object reference this Exception is thrown by JRE please help!!

尝试在空对象引用上调用虚拟方法“void java.io.BufferedReader.close()”此异常由 JRE 引发,请帮助!

here is the class

这是课程

package com.example.MovieMania.fragmentTv;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;





import com.example.MovieMania.R;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.AdapterView.OnItemClickListener;

public class BackgroundTaskTv extends AsyncTask<String, Void, String[]> {

    final String DEF_BASE_URL = "http:api.themoviedb.org/3/tv/popular?[api_key]";

    private final Context context;

    public BackgroundTaskTv(Context context) {
        this.context = context;
    }

    public static String JsonStr;  // so that JSONstring can be used by other activities

    private String[] jsonParse(String movieJsonStr) throws JSONException {

        final String POSTER_PATH = "poster_path"; // JSON STRING PARSING AND
                                                    // RETURN
                                                    // POSTER PATHS

        JSONObject jsonObj = new JSONObject(movieJsonStr);
        JSONArray resultArray = jsonObj.getJSONArray("results");

        int len =resultArray.length();
        String[] posters = new String[len];
        for (int i = 0; i < len; i++) {
            posters[i] = resultArray.getJSONObject(i).getString(POSTER_PATH);
        }

        for (String res : posters)
            Log.v(POSTER_PATH, res);

        return posters;

    }

    @Override
    protected String[] doInBackground(String... params) {



        String movieJsonStr = null;
        InputStream inputStream = null;


        String FINAL_URL=DEF_BASE_URL;
        ImageAdapterTv.poster_paths.clear();

        BufferedReader reader = null;
        HttpURLConnection urlConnection = null; // READ THE INPUTSTREAM AND
                                                // GET THE JSONSTRING
        try {
            URL url = new URL(FINAL_URL);
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.connect();

            // Read the input stream into a String
            inputStream = urlConnection.getInputStream();
            StringBuffer buffer = new StringBuffer();
            if (inputStream == null) {
                // Nothing to do.
                return null;
            }

            reader = new BufferedReader(new InputStreamReader(inputStream));

            String line;
            while ((line = reader.readLine()) != null) {
                // Since it's JSON, adding a newline isn't necessary (it
                // won't affect parsing)
                // But it does make debugging a *lot* easier if you print
                // out the completed
                // buffer for debugging.
                buffer.append(line + "\n");
            }

            if (buffer.length() == 0) {
                // Stream was empty. No point in parsing.
                return null;
            }

            movieJsonStr = buffer.toString();
            JsonStr=movieJsonStr;

            Log.v("Tv string: ", movieJsonStr);
        } catch (Throwable e) {
            Log.e("backgroundtask", "EXCEPTION", e);
        } finally {
            urlConnection.disconnect();
            try {
                reader.close();
                inputStream.close();
            } catch (IOException e) {
                Log.e("READER.CLOSE()", e.toString());
            }
        }

        try {
            return jsonParse(movieJsonStr);
        } catch (JSONException e) {
            Log.e("BACKGROUNDTASK", "EXCEPTION FROM jsonParse()", e);
        }

        return null;
    }

    @Override
    protected void onPostExecute(String[] result) {
        if (ImageAdapterTv.poster_paths.isEmpty()) {
            for (String s : result) {
                ImageAdapterTv.poster_paths.add(s);
            }
        }

        final Activity activity = (Activity) context;
        activity.runOnUiThread(new Runnable() {
            @Override
            // this code is written so that the grid view is populated after
            // backgroundTask
            public void run() { // produce results so that there is no blank
                                // screen on launch
                GridView grid = (GridView) activity.findViewById(R.id.gridview_tv);
                grid.setAdapter(new ImageAdapterTv(context));

                grid.setOnItemClickListener(new OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> parent, View view,
                            int position, long id) {
                        String path=ImageAdapterTv.poster_paths.get(position);
                        Intent intent=new Intent(context,DetailActivityTv.class);
                        intent.putExtra("poster", path);
                        intent.putExtra("POSITION", position);
                        activity.startActivity(intent);
                        }
                });

                }
        });
    }

}

It is a background thread which is getting the json response from an api I dont know why this exception is thrown.

这是一个后台线程,它从一个 api 获取 json 响应我不知道为什么会抛出这个异常。

采纳答案by Ahmed Sayed

if exception happened before initializing the reader it will lead to this error because reader.close() is placed in finally block. It's good practice to always check for null before closing resources in finally

如果在初始化读取器之前发生异常,则会导致此错误,因为 reader.close() 位于 finally 块中。在 finally 中关闭资源之前始终检查 null 是一种很好的做法

if(reader != null)
    reader.close();
if(inputStream != null)
    inputStream.close();

回答by user2413972

You need to check "Null" in the finally . Something is happening, and reader not created.

您需要在 finally 中检查“Null”。有些事情正在发生,而读者没有被创造出来。

            try {
                if (reader != null) reader.close();
                if (inputStream!= null) inputStream.close();
            } catch (IOException e) {
                Log.e("READER.CLOSE()", e.toString());
            }

You do return null, but the finally is done. And in it BufferedReader reader = null;. See example:

你做return null,但最后完成了。而在其中BufferedReader reader = null;。见示例

public static void main(String[] args){
    System.out.println(0);
    Object o = get();
    System.out.println(2);
}

public static Object get(){
    try {
        System.out.println(1);
        return null;
    } catch (Exception e){

    } finally {
        System.out.println("finally");
    }
    return null;
}

Output:

输出:

0 1 finally 2

0 1 最后 2

回答by Sudheer

It maybe caused because of exception in your urlconnection or your inputstream is null.

这可能是由于您的 urlconnection 中的异常或您的输入流为空引起的。

if (inputStream == null)
return null;

Your code will run finally block if exception is thrown or return is called from inputstream null checking.

如果抛出异常或从 inputstream 空检查中调用 return,您的代码将运行 finally 块。

Reader object to be created using inputstream is never created. So when you try close() method it's throwing null pointer exception.

永远不会创建要使用 inputstream 创建的 Reader 对象。因此,当您尝试 close() 方法时,它会抛出空指针异常。

You should always use null checking before using close() method on streams and readers, writers.

在对流和读取器、写入器使用 close() 方法之前,您应该始终使用空检查。

回答by Sasha

As it is seen from the discription the exception occurs when you are trying to close the BufferedReader readerobject in the finallyblock as it is nullat that moment. It happens because you get some other exception in your tryblock wich occurs before you initialize the reader or because your returnstatement is called, i.e somewhere in this piece of code:

从描述中可以看出,当您尝试关闭块中的BufferedReader reader对象时会发生异常。发生这种情况是因为您在初始化读取器之前在块中遇到了其他一些异常,或者因为调用了您的语句,即在这段代码中的某处:finallynulltryreturn

        URL url = new URL(FINAL_URL);
        urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setRequestMethod("GET");
        urlConnection.connect();

        // Read the input stream into a String
        inputStream = urlConnection.getInputStream();
        StringBuffer buffer = new StringBuffer();
        if (inputStream == null) {
            // Nothing to do.
            return null;
        }

To avoid such situation, you should check your readerand inputStreamfor nullbefore closing like this:

为避免这种情况,您应该在关闭之前检查您的readerinputStreamnull如下所示:

if(reader != null) {
    reader.close;
    reader = null;
}
if(inputStream != null) {
    inputStream.close;
    inputStream = null;
}

Besides take a look at this post about catching Throwables: Is it a bad practice to catch Throwable?

除了看看这篇关于捕获 Throwables 的帖子:捕获 Throwable 是一种不好的做法吗?

Anyway, I think you shall find out why does this flow takes place as it is not what you want as far as I can understand

无论如何,我想你会发现为什么会发生这种流动,因为据我所知,这不是你想要的

Why have you moved this block of code outside the first try-catch?:

你为什么把这段代码移到第一个之外try-catch?:

try {
        return jsonParse(movieJsonStr);
    } catch (JSONException e) {
        Log.e("BACKGROUNDTASK", "EXCEPTION FROM jsonParse()", e);
    }

You can catch multiple types of exceptions from one try{}, you just have to specify them one by one. As written above, when something goes wrong(and it does) you are finishing previous try-catch block before creating reader and everything after that. Therefore in this place your movieJsonStr is also null, and you are passing it forward to create a JSONOblectfrom it. This is where your next exception comes from. Move the return jsonParse(movieJsonStr);string to the place where you are certain it is the string you want to process.

您可以从 one 中捕获多种类型的异常try{},您只需要将它们一一指定。如上所述,当出现问题时(并且确实出现了问题),您将在创建读取器之前完成之前的 try-catch 块以及之后的所有内容。因此在这个地方你的 movieJsonStr 也是空的,你正在传递它以从中创建一个JSONOblect。这是您的下一个异常的来源。将return jsonParse(movieJsonStr);字符串移动到您确定它是您要处理的字符串的位置。

回答by shan.singh001

sometimes this is the problem because of you are closing the BufferedReader which is not assigned any value or its value is null. so it throwing exception java.lang.NullPointerException: Attempt to invoke virtual method 'void java.io.BufferedReader.close()' on a null object referenceto overcome this problem : goto your manifest file and give INTERNET permission

有时这是问题所在,因为您正在关闭未分配任何值或其值为 null 的 BufferedReader。所以它抛出异常java.lang.NullPointerException: Attempt to invoke virtual method 'void java.io.BufferedReader.close()' on a null object reference来解决这个问题:转到你的清单文件并授予 INTERNET 权限