在我的代码中,我正在对null
进行大量检查,以便我不会得到NullPointerException
通常我只是这样做:
if(variable != null){
//do something with the variable
}
以下是否更好,或仅仅是个事或个人信仰?
if( !variable.equals(null) ){
//do something with the variable
}
是否有更有效的方法进行此检查?
是的,我确实已经完成了我的研究,但我似乎找不到具体的证据来证明这一点。PS这是Avoiding != null statements的 NOT 副本,最好的答案是您应该使用Assert,它不能用于运行代码而不仅仅是显示消息,或者实际上抛出我不想要的异常。这篇文章正在解决同一主题的不同问题。
答案 0 :(得分:4)
if(!variable.equals(null) ){
//do something with the variable
}
如果变量为空,则发生NPE。第一种方法要好得多。
编辑:
使用可选:
请考虑您有Person
个对象,并希望getSalary()
。不幸的是,年龄可能为空 - 在这种情况下,您需要默认值。你可以做Integer salary = Optional.ofNullable(person.getSalary()).orElse(2000)
。如果工资为空,它将从人或2000返回salarty。
答案 1 :(得分:2)
正如其他人已经说过的,变种
public class MainFragment extends BrowseFragment implements LoaderManager.LoaderCallbacks<List<Module>> {
private static final int MODULES_LOADER_ID = 100;
private ArrayObjectAdapter mRowsAdapter;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setupUIElements();
setupRowAdapter();
setupListeners();
getLoaderManager().initLoader(MODULES_LOADER_ID, null, this);
}
private void setupUIElements() {
setTitle(getActivity().getString(R.string.app_name));
setBadgeDrawable(getResources().getDrawable(R.drawable.title, getActivity().getTheme()));
setHeadersTransitionOnBackEnabled(false);
setBrandColor(getActivity().getResources().getColor(R.color.fastlane_background));
setHeadersState(HEADERS_DISABLED);
}
private void setupRowAdapter() {
mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
setAdapter(mRowsAdapter);
}
private void setupListeners() {
setOnItemViewSelectedListener(new ItemViewSelectedListener());
setOnItemViewClickedListener(new ItemViewClickedListener());
}
private void loadModules(List<Module> modules) {
ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new ModulesCardPresenter());
for (Module module : modules) {
listRowAdapter.add(module);
}
HeaderItem header = new HeaderItem(0, "Меню");
mRowsAdapter.add(new ListRow(header, listRowAdapter));
}
@Override
public Loader<List<Module>> onCreateLoader(int id, Bundle args) {
switch (id) {
case MODULES_LOADER_ID:
return new ModulesLoader(getActivity());
default:
return null;
}
}
@Override
public void onLoadFinished(Loader<List<Module>> loader, List<Module> data) {
switch (loader.getId()) {
case MODULES_LOADER_ID:
loadModules(data);
break;
}
}
@Override
public void onLoaderReset(Loader<List<Module>> loader) {
}
static class ModulesLoader extends SimpleAsyncTaskLoader<List<Module>> {
public ModulesLoader(Context context) {
super(context);
}
@Override
public List<Module> loadInBackground() {
Call<Modules> mCall = ServiceHolder.getService()
.getModules(Constants.GET_MODULES_REQUEST);
try {
return mCall.execute().body().getModules();
} catch (Exception e) {
e.printStackTrace();
return Collections.EMPTY_LIST;
}
}
}
private final class ItemViewSelectedListener implements OnItemViewSelectedListener {
@Override
public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
RowPresenter.ViewHolder rowViewHolder, Row row) {
}
}
private final class ItemViewClickedListener implements OnItemViewClickedListener {
@Override
public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
RowPresenter.ViewHolder rowViewHolder, Row row) {
}
}
当变量为null时,可以自己NPE。此外,您必须确保equals方法对于您使用的所有对象类型也是空的。因此,如果您绝对需要检查,请使用==。
至于更好的解决方案(我们在这里基于意见):我认为这种过度的空检查是脆弱软件和次优接口定义的标志。我目前尝试做的越来越多是使用javax.validation注释@NotNull来强化我的接口并摆脱所有这些运行时检查:
08-18 16:06:08.331 29647-29647/ E/AndroidRuntime: FATAL EXCEPTION: main
Process: , PID: 29647
**java.lang.RuntimeException: Unable to start activity ComponentInfo{.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.app.Fragment.getView()' on a null object reference**
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
**Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.app.Fragment.getView()' on a null object reference**
at android.support.v17.leanback.app.BrowseFragment.onStart(BrowseFragment.java:1511)
at android.app.Fragment.performStart(Fragment.java:2244)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1002)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1148)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1130)
at android.app.FragmentManagerImpl.dispatchStart(FragmentManager.java:1958)
at android.app.FragmentController.dispatchStart(FragmentController.java:163)
at android.app.Activity.performStart(Activity.java:6274)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) </code>
...试一试:)
修改(作为评论的答案,因为我需要代码格式化):
这是我当前日食设置的完整剪切和粘贴示例:
if(!variable.equals(null))
确保导入的类型确实是javax.validation.constraints.NotNull(因为其他框架也有NotNull注释,可以用不同的方式定义)。对于eclipse,您还必须在JavaCompiler / Errors / Warnings下的项目设置中选中“启用基于注释的空值分析”并自定义要使用的注释,因为eclipse默认为一些自制的注释。可以通过相同设置页面中使用默认注释的复选框后面的“配置”链接访问自定义。希望有所帮助!
答案 2 :(得分:2)
或者您可以使用Java 8中的java.util.Optional。
非常好的例子在JavaCodeGeeks上。
可选通常用于java.util.stream lambdas用于&#34;功能样式的操作&#34;。
答案 3 :(得分:1)
有两种方法:
public void calculate(Class variable) {
Assert.notNull(variable, "variable was null");
//calculations
}
//and
if (variable == null) {
//bad
} else {
calculate(variable);
}
第二个是最常见的一个。如果您的变量是String
,请考虑使用Guava.StringUtils
一个非常棒的isBlank
方法检查String
是null
还是""
汇总:
if (variable == null) {
//bad
} else {
//good
}
以上是标准方法。更好的方法是:
private boolean isNull(Class variable) {
return variable == null;
}
if (isNull(variable)) {
} else {
}
答案 4 :(得分:0)
我曾经一直调用以下方法来检查nullpointer异常
public static boolean isAvailable(Object data) {
return ((data!=null) && (data.toString().trim().length() > 0));
}