You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
2.6 KiB

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package codetoanalyze.java.nullsafe;
import javax.annotation.Nullable;
/**
* Nullsafe has a feature: field nullability is memoized within a method. In other words, nullsafe
* assumes:
*
* <ol>
* <li>a) There will be no tricky multithreading.
* <li>b) If a field is set to non-null, the method won't call another method that will nullify it
* back.
* </ol>
*
* <p>NOTE: This feature is unsound, but assumptions a) and b) mostly hold for real codebases, so
* here nullsafe tradeoffs theoretical unsoundness for practical usability.
*
* <p>This class tests basic properties of this feature.
*/
public class FieldNullabilityMemoization {
private @Nullable Object nullable;
void dereferenceIsBAD() {
nullable.toString();
}
void dereferenceViaLocalVarIsBAD() {
Object a = nullable;
a.toString();
}
void dereferenceAfterCheckIsOK() {
if (nullable != null) {
// Theoretically, a different thread could modify the field right here.
// But practically, if such things can happen, we have much bigger problems than nullability.
nullable.toString();
}
}
void dereferenceAfterCheckViaLocalVarIsOK() {
if (nullable != null) {
// Theoretically, a different thread could modify the field right here.
// But practically, if such things can happen, we have much bigger problems than nullability.
Object a = nullable;
a.toString();
}
}
void dereferenceAfterNonnullAssignmentIsOK() {
nullable = "";
// Theoretically, a different thread could modify the field right here.
// But practically, if such things can happen, we have much bigger problems than nullability.
nullable.toString();
}
void dereferenceAfterNonnullAssignmentViaLocalVarIsOK() {
nullable = "";
// Theoretically, a different thread could modify the field right here.
// But practically, if such things can happen, we have much bigger problems than nullability.
Object a = nullable;
a.toString();
}
void FN_nullabilityIsPreservedEvenOnMethodCalls() {
nullable = "";
// Calling methods does not invalidate nullability of fields,
// even if they theoritically can nullify the field.
// In practice, this happens extremely rarely, but in this synthetic example
// this will lead to an NPE.
nullify();
// Uncaught NPE
nullable.toString();
}
private void nullify() {
nullable = null;
}
}