public boolean canCompleteNormally(Statement statement) {
        if (!isReachable(statement)) {
            return false;
        }
        GenericVisitor<Boolean, Void> visitor = new GenericVisitorAdapter<Boolean, Void>(){
            @Override
            public Boolean visit(BlockStmt n, Void arg) {
                // An empty block that is not a switch block can complete normally iff it is reachable
                if (n.isEmpty() && !parentIs(statement, SwitchStmt.class)) {
                    return isReachable(statement);
                }
                // A non-empty block that is not a switch block can complete normally iff the last statement in
                // it can complete normally.
                if (!n.isEmpty() && !parentIs(statement, SwitchStmt.class)) {
                    return canCompleteNormally(n.getStatement(n.getStatements().size() - 1));
                }
                throw new UnsupportedOperationException();
            }

            @Override
            public Boolean visit(LabeledStmt n, Void arg) {
                // A labeled statement can complete normally if at least one of the following is true:
                // – The contained statement can complete normally.
                // – There is a reachable break statement that exits the labeled statement.
                throw new UnsupportedOperationException();
            }

            @Override
            public Boolean visit(EmptyStmt n, Void arg) {
                // An empty statement can complete normally iff it is reachable.
                return isReachable(n);
            }

            @Override
            public Boolean visit(LocalClassDeclarationStmt n, Void arg) {
                // A local class declaration statement can complete normally iff it is reachable.
                return isReachable(n);
            }

            @Override
            public Boolean visit(IfStmt n, Void arg) {
                if (n.getElseStmt().isPresent()) {
                    // An if-then-else statement can complete normally iff the then-statement can
                    // complete normally or the else-statement can complete normally.
                    return canCompleteNormally(n.getThenStmt()) || canCompleteNormally(n.getElseStmt().get());
                } else {
                    // An if-then statement can complete normally iff it is reachable.
                    return isReachable(n);
                }
            }

            @Override
            public Boolean visit(AssertStmt n, Void arg) {
                // An assert statement can complete normally iff it is reachable.
                return isReachable(n);
            }

            @Override
            public Boolean visit(ExpressionStmt n, Void arg) {
                // A local variable declaration statement can complete normally iff it is reachable.
                if (n.getExpression() instanceof VariableDeclarationExpr) {
                    VariableDeclarationExpr expr = (VariableDeclarationExpr) n.getExpression();
                    return isReachable(n);
                }
                // An expression statement can complete normally iff it is reachable.
                return isReachable(n);
            }
        };
        return statement.accept(visitor, null);
    }
public boolean canCompleteNormally(Statement statement) {
        if (!isReachable(statement)) {
            return false;
        }
        GenericVisitor<Boolean, Void> visitor = new GenericVisitorAdapter<Boolean, Void>(){
            @Override
            public Boolean visit(BlockStmt n, Void arg) {
                
                if (n.isEmpty() && !parentIs(statement, SwitchStmt.class)) {
                    return isReachable(statement);
                }
                
                
                if (!n.isEmpty() && !parentIs(statement, SwitchStmt.class)) {
                    return canCompleteNormally(n.getStatement(n.getStatements().size() - 1));
                }
                throw new UnsupportedOperationException();
            }

            @Override
            public Boolean visit(LabeledStmt n, Void arg) {
                
                
                
                throw new UnsupportedOperationException();
            }

            @Override
            public Boolean visit(EmptyStmt n, Void arg) {
                
                return isReachable(n);
            }

            @Override
            public Boolean visit(LocalClassDeclarationStmt n, Void arg) {
                
                return isReachable(n);
            }

            @Override
            public Boolean visit(IfStmt n, Void arg) {
                if (n.getElseStmt().isPresent()) {
                    
                    
                    return canCompleteNormally(n.getThenStmt()) || canCompleteNormally(n.getElseStmt().get());
                } else {
                    
                    return isReachable(n);
                }
            }

            @Override
            public Boolean visit(AssertStmt n, Void arg) {
                
                return isReachable(n);
            }

            @Override
            public Boolean visit(ExpressionStmt n, Void arg) {
                
                if (n.getExpression() instanceof VariableDeclarationExpr) {
                    VariableDeclarationExpr expr = (VariableDeclarationExpr) n.getExpression();
                    return isReachable(n);
                }
                
                return isReachable(n);
            }
        };
        return statement.accept(visitor, null);
    }
public boolean canCompleteNormally ( Statement statement ) { if ( ! isReachable ( statement ) ) { return false ; } GenericVisitor < Boolean , Void > visitor = new GenericVisitorAdapter < Boolean , Void > ( ) { @ Override public Boolean visit ( BlockStmt n , Void arg ) { // An empty block that is not a switch block can complete normally iff it is reachable if ( n . isEmpty ( ) && ! parentIs ( statement , SwitchStmt . class ) ) { return isReachable ( statement ) ; } // A non-empty block that is not a switch block can complete normally iff the last statement in // it can complete normally. if ( ! n . isEmpty ( ) && ! parentIs ( statement , SwitchStmt . class ) ) { return canCompleteNormally ( n . getStatement ( n . getStatements ( ) . size ( ) - 1 ) ) ; } throw new UnsupportedOperationException ( ) ; } @ Override public Boolean visit ( LabeledStmt n , Void arg ) { // A labeled statement can complete normally if at least one of the following is true: // – The contained statement can complete normally. // – There is a reachable break statement that exits the labeled statement. throw new UnsupportedOperationException ( ) ; } @ Override public Boolean visit ( EmptyStmt n , Void arg ) { // An empty statement can complete normally iff it is reachable. return isReachable ( n ) ; } @ Override public Boolean visit ( LocalClassDeclarationStmt n , Void arg ) { // A local class declaration statement can complete normally iff it is reachable. return isReachable ( n ) ; } @ Override public Boolean visit ( IfStmt n , Void arg ) { if ( n . getElseStmt ( ) . isPresent ( ) ) { // An if-then-else statement can complete normally iff the then-statement can // complete normally or the else-statement can complete normally. return canCompleteNormally ( n . getThenStmt ( ) ) || canCompleteNormally ( n . getElseStmt ( ) . get ( ) ) ; } else { // An if-then statement can complete normally iff it is reachable. return isReachable ( n ) ; } } @ Override public Boolean visit ( AssertStmt n , Void arg ) { // An assert statement can complete normally iff it is reachable. return isReachable ( n ) ; } @ Override public Boolean visit ( ExpressionStmt n , Void arg ) { // A local variable declaration statement can complete normally iff it is reachable. if ( n . getExpression ( ) instanceof VariableDeclarationExpr ) { VariableDeclarationExpr expr = ( VariableDeclarationExpr ) n . getExpression ( ) ; return isReachable ( n ) ; } // An expression statement can complete normally iff it is reachable. return isReachable ( n ) ; } } ; return statement . accept ( visitor , null ) ; }
See JLS 14.21
See JLS 14 . 21