理解'finally'块

jai*_*jai 5 java finally try-finally

我写了七个测试用例来理解finally块的行为.如何finally运作背后的逻辑是什么?

package core;

public class Test {
    public static void main(String[] args) {
        new Test().testFinally();
    }

    public void testFinally() {
        System.out.println("One = " + tryOne());
        System.out.println("Two = " + tryTwo());
        System.out.println("Three = " + tryThree());
        System.out.println("Four = " + tryFour());
        System.out.println("Five = " + tryFive());
        System.out.println("Six = " + trySix());
        System.out.println("Seven = " + trySeven());
    }

    protected StringBuilder tryOne() {
        StringBuilder builder = new StringBuilder();
        try {
            builder.append("Cool");
            return builder.append("Return");
        }
        finally {
            builder = null;
        }
    }

    protected String tryTwo() {
        String builder = "Cool";
        try {
            return builder += "Return";
        }
        finally {
            builder = null;
        }
    }

    protected int tryThree() {
        int builder = 99;
        try {
            return builder += 1;
        }
        finally {
            builder = 0;
        }
    }

    protected StringBuilder tryFour() {
        StringBuilder builder = new StringBuilder();
        try {
            builder.append("Cool");
            return builder.append("Return");
        }
        finally {
            builder.append("+1");
        }
    }

    protected int tryFive() {
        int count = 0;
        try {
            count = 99;
        }
        finally {
            count++;
        }
        return count;
    }

    protected int trySix() {
        int count = 0;
        try {
            count = 99;
        }
        finally {
            count = 1;
        }
        return count;
    }

    protected int trySeven() {
        int count = 0;
        try {
            count = 99;
            return count;
        }
        finally {
            count++;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么builder = null不工作?

为什么builder.append("+1")工作,而count++(在trySeven()),并没有工作?

Mat*_*hen 10

一旦你做了返回,覆盖它的唯一方法是做另一次返回(如从Java中的finally块返回,这几乎总是一个坏主意),或者突然完成.你的测试永远不会从最后回来.

JLS§ 14.1定义突然完成.突然完成类型之一是返回.由于返回,1,2,3,4和7中的try块突然完成.正如§14.20.2所解释的那样,如果try块除了throw之外突然因R而完成,则立即执行finally块.

如果finally块正常完成(这意味着没有返回,除其他外),"try语句因为R而突然完成".换句话说,尝试启动的返回保持不变; 这适用于所有测试.如果你从finally返回,"try语句突然完成原因S(并且原因R被丢弃)." (这里是新的重要回报).

所以在tryOne中,如果你这样做:

finally {
            builder = null;
            return builder;
        }
Run Code Online (Sandbox Code Playgroud)

这个新的返回S将覆盖原始返回R.

对于builder.append("+1")in tryFour,请记住StringBuilder是可变的,因此您仍然返回对try中指定的同一对象的引用.你只是在做最后一分钟的突变.

tryFive并且trySix是直截了当的.由于try中没有返回,try和finally都正常完成,并且执行方式就像没有try-finally一样.