Я использую аннотации, чтобы гарантировать, что параметр будет не нулевым, если предположить, что это вызовет проверку компилятора.Android: NullPointerException несмотря на @NonNull
public @Nullable ApplicationAccount accountForKey(@NonNull String key) {
return accounts.get(key);
}
Однако, запустив этот код я получаю NullPointerException именно на этой линии
java.util.concurrent.ConcurrentHashMap.get (ConcurrentHashMap.java:883)
Какой смысл аннотаций тогда?
Еще более затемнение, если я пишу дополнительные проверки, как этот
return key!=null?accounts.get(key):null;
Android Studio предупреждает меня, что чек бесполезно!
Update: полный стек вызовов:
Caused by java.lang.NullPointerException
at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:883)
at co.getcontrol.services.MerchantCenter.accountForKey(MerchantCenter.java:72)
at co.getcontrol.model.customers.CustomersAggregator.loadCustomerDetails(CustomersAggregator.java:91)
at co.getcontrol.model.customers.CustomerDetailsPresenter.callData(CustomerDetailsPresenter.java:39)
at co.getcontrol.reskin.ui.customers.CustomerDetailsViewFragment.onCreateView(CustomerDetailsViewFragment.java:152)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1974)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617)
at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:339)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:602)
at co.getcontrol.ui.ControlActivity.onStart(ControlActivity.java:13)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1174)
at android.app.Activity.performStart(Activity.java:5353)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2352)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2441)
at android.app.ActivityThread.access$900(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5345)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:828)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:644)
at dalvik.system.NativeStart.main(NativeStart.java)
время компиляции и выполнения разные вещи ... Это @NonNull не будет волшебно предотвратить нулевое значение, так как вы только что видели ...И вот почему мне не нравятся эти аннотации. – ppeterka
Хм, для меня это исключает весь смысл использования аннотаций. Без аннотации я теперь должен заботиться о проверке указателя. Если я напишу @NonNull, то я автоматически делегирую эту обязанность кому-то (компилятор). Я ожидаю тогда, по крайней мере, тот код, который * использует * этот метод, должен вызывать ошибку компиляции/предупреждение, когда он не проверяет значение null. –
Есть полезные аннотации. Это бесполезно. И yep, вы должны проверить свои ссылки (нет указателей на Java!) ... И вы не можете делегировать это во время компиляции! Не могу. Невозможно. Подумайте об этом: вы пишете лучшую JSON-библиотеку в мире, компилируете ее, выпускаете, а кто-то еще называет ее большим толстым нулем. Как мог компилятор поймать это? – ppeterka