boolean (final PsiExpression initializer, final PsiModifierListOwner ctrOrInitializer, PsiField field) { if (initializer == null) return false; if (!ExceptionUtil.getThrownCheckedExceptions(initializer).isEmpty()) return false; final Ref<Boolean> result = new Ref<>(Boolean.TRUE); PsiClass aClass = field.getContainingClass(); if (aClass == null) return false; initializer.accept(new JavaRecursiveElementWalkingVisitor() { @Override public void visitReferenceExpression(@NotNull PsiReferenceExpression expression) { super.visitReferenceExpression(expression); PsiElement resolved = expression.resolve(); if (resolved == null) return; if (resolved == field) { result.set(Boolean.FALSE); return; } if (PsiTreeUtil.isAncestor(ctrOrInitializer, resolved, false) && !PsiTreeUtil.isAncestor(initializer, resolved, false)) { // resolved somewhere inside constructor but outside initializer result.set(Boolean.FALSE); return; } if (resolved instanceof PsiMethod) { resolved = PropertyUtil.getFieldOfGetter((PsiMethod)resolved); } if (resolved instanceof PsiField && ((PsiField)resolved).getContainingClass() == aClass) { // refers to another field/method of the same class (except referring from non-static member to static and // referring to initialized field which is probably ok) boolean nonStaticRefersToStatic = !field.hasModifierProperty(PsiModifier.STATIC) && ((PsiField)resolved).hasModifierProperty(PsiModifier.STATIC); if (nonStaticRefersToStatic) return; boolean initializedField = ((PsiField)resolved).getInitializer() != null; if (initializedField) { PsiField[] fields = aClass.getFields(); int indexSource = ArrayUtil.indexOf(fields, field); int indexTarget = ArrayUtil.indexOf(fields, resolved); if (indexTarget >= 0 && indexSource > indexTarget) { // we can refer to already initialized field if it's declared before our field return; } } result.set(Boolean.FALSE); } } }); return result.get().booleanValue(); }