JLS参考:https://docs.oracle.com/javase/specs/jls/se7/html/jls-16.html

This pass implements dataflow analysis for Java programs.

1、Liveness analysis checks that every statement is reachable.

2、Exception analysis ensures that every checked exception that is thrown is declared or caught.

3、Definite(一定的、确定的) assignment analysis ensures that each variable is assigned when used.

eg1:

任何局部变量在使用前要进行初始化,包括基本类型,如下将报错:

int i;
if(i==2){ // 报错,局部变量i未初始化

}

Definite unassignment analysis ensures that no final variable is assigned more than once(不止一次).

eg2:

final int i;
i = 1;
i = 22; // The final local variable i may already have been assigned

The JLS has a number of problems in the specification of these flow analysis problems.This implementation attempts to address those issues.

JLS对数据流分析还存在几个问题,下面试着解决这些问题。

First, there is no accommodation for a finally clause that cannot complete normally.

1、For liveness analysis, an intervening finally clause can cause a break, continue, or return not to reach its target.

eg3:

for(int i=0;i<2;i++){
	System.out.println(i);
	try{
		return;
	}finally{
		continue;
	}
}

输出的结果为:0 1。可以看到finally中的continue让return没有达到它使用的目的。  

2、For exception analysis, an intervening finally clause can cause any exception to be "caught".

eg1:

什么是intervening finally,就比如finally中有return 、continue等有控制流程转移的语句。

for(int i=0;i<2;i++){
			try{
				System.out.println("a");
				break;
			}catch(Exception ex){

			}finally{ // finally block does not complete normally
				System.out.println("b");
				continue;
			}
}  

输出为:a b a b

@SuppressWarnings("finally")
private boolean isReturnWithinFinally() {
		try {
			throw new IOException();
		} finally {
			return true; // This hides the exception
		}
}

java里面的异常分为可不获和不可捕获两类,即便使用到catch块,也会导致非捕获的错误被finally吃掉。因此,return一定要放到finally外面。

关于intervening finally 参考文章:https://www.cnblogs.com/extjs4/p/9375400.html

3、For DA/DU analysis, the finally clause can prevent a transfer of control(控制权的转移) from propagating(传播) DA/DU
state to the target. In addition(另外), code in the finally clause can affect the DA/DU status of variables.

4、For try statements, we introduce the idea of a variable being definitely unassigned "everywhere" in a block.
A variable V is "unassigned everywhere" in a block iff(if and only if) it is unassigned at the beginning of the block and there is no reachable assignment to V in the block.

An assignment V=e is reachable iff V is not DA after e. Then we can say that V is DU at the beginning of the catch block iff V is DU everywhere in the try block.

Similarly,V is DU at the beginning of the finally block iff V is DU everywhere in the try block and in every catch block.

说明:try statement的文法结构如下:

TryStatement:
    try Block Catches
    try Block Catchesopt Finally
    TryWithResourcesStatement

Specifically, the following bullet is added to 16.2.2

       V is unassigned everywhere in a block if it is
       unassigned before the block and there is no reachable
       assignment to V within the block.   

In 16.2.15, the third bullet (and all of its sub-bullets) for all try blocks is changed to

       V is definitely unassigned before a catch block iff V is
       definitely unassigned everywhere in the try block.
   

The last bullet (and all of its sub-bullets) for try blocks that have a finally block is changed to

       V is definitely unassigned before the finally block iff
       V is definitely unassigned everywhere in the try block
       and everywhere in each catch block of the try statement.   

In addition,

       V is definitely assigned at the end of a constructor iff
       V is definitely assigned after the block that is the body
       of the constructor and V is definitely assigned at every
       return that can return from the constructor.

In addition, each continue statement with the loop as its target is treated as a jump to the end of the loop body,and "intervening" finally clauses are treated as follows:

V is DA "due to(归因于) the continue" iff V is DA before the continue statement or V is DA at the end of any intervening finally block.

V is DU "due to the continue" iff any intervening finally cannot complete normally or V is DU at the end of every intervening finally block. This "due to the continue" concept is then used in the spec for the loops.

Similarly, break statements must consider intervening finally blocks.

For liveness analysis, a break statement for which any intervening finally cannot complete normally is not considered to cause the target statement to be
able to complete normally. Then we say V is DA "due to the break" iff V is DA before the break or V is DA
at the end of any intervening finally block. V is DU "due to the break" iff any intervening finally cannot complete normally
or V is DU at the break and at the end of every intervening finally block. (I suspect this latter condition can be simplified.)
This "due to the break" is then used in the spec for all statements that can be "broken".

The return statement is treated similarly. V is DA "due to a return statement" iff V is DA before the return statement
or V is DA at the end of any intervening finally block. Note that we don't have to worry about the return expression because this concept is only used for construcrors.

There is no spec in JLS2 for when a variable is definitely assigned at the end of a constructor, which is needed for
final fields (8.3.1.2). We implement the rule that V is DA at the end of the constructor iff it is DA and the end of
the body of the constructor and V is DA "due to" every return of the constructor.

Intervening finally blocks similarly affect exception analysis. An intervening finally that cannot complete normally allows us to ignore an otherwise uncaught exception.

To implement the semantics of intervening finally clauses, all nonlocal transfers (break, continue, return, throw,
method call that can throw a checked exception, and a constructor invocation that can thrown a checked exception)
are recorded in a queue, and removed from the queue when we complete processing the target of the nonlocal transfer.
This allows us to modify the queue in accordance with the above rules when we encounter a finally clause.
The only exception to this [no pun intended] is that checked exceptions that are known to be caught or declared
to be caught in the enclosing method are not recorded in the queue, but instead are recorded in a global variable
"Set thrown" that records the type of all exceptions that can be thrown.

Other minor issues the treatment of members of other classes (always considered DA except that within an anonymous class constructor, where DA status from the enclosing scope is preserved),

treatment of the case expression (V is DA before the case expression iff V is DA after the switch expression), treatment of variables declared in a
switch block (the implied DA/DU status after the switch expression is DU and not DA for variables defined in a switch block),
the treatment of boolean ?: expressions (The JLS rules only handle b and c non-boolean; the new rule is that
if b and c are boolean valued, then V is (un)assigned after a?b:c when true/false iff V is (un)assigned after b
when true/false and V is (un)assigned after c when true/false).

There is the remaining question of what syntactic forms constitute(组成) a reference to a variable. It is conventional to
allow this.x on the left-hand-side to initialize a final instance field named x, yet this.x isn't considered a "use" when appearing on a right-hand-side in most implementations.

Should parentheses affect what is considered a variable reference?(括号会影响被视为变量引用的内容)The simplest rule would be to allow unqualified forms only, parentheses optional, and phase out support for assigning to a final field via this.x.

Flow类的更多相关文章

  1. Flow类注释解读

    参考: (1)https://docs.oracle.com/javase/specs/jls/se7/html/jls-16.html (2)https://docs.oracle.com/java ...

  2. Flow类中的resolveBreaks与resolveContinues

    /** Resolve all continues of this statement. */ boolean resolveContinues(JCTree tree) { boolean resu ...

  3. Java类的继承与多态特性-入门笔记

    相信对于继承和多态的概念性我就不在怎么解释啦!不管你是.Net还是Java面向对象编程都是比不缺少一堂课~~Net如此Java亦也有同样的思想成分包含其中. 继承,多态,封装是Java面向对象的3大特 ...

  4. JVM-程序编译与代码早期(编译期)优化

    早期(编译期)优化 一.Javac编译器 1.Javac的源代码与调试 Javac的源代码放在JDK_SRC_HOME/langtools/src/shares/classes/com/sun/too ...

  5. Javac早期(编译期)

    从Sun Javac的代码来看,编译过程大致可以分为3个过程: 解析与填充符号表过程. 插入式注解处理器的注解处理过程. 分析与字节码生成过程. Javac编译动作的入口是com.sun.tools. ...

  6. OpenStack Cinder源代码流程简析

    版权声明:本博客欢迎转载,转载时请以超链接形式标明文章原始出处!谢谢! 博客地址:http://blog.csdn.net/i_chips 一.概况 OpenStack的各个模块都有对应的client ...

  7. Java 9 揭秘(17. Reactive Streams)

    Tips 做一个终身学习的人. 在本章中,主要介绍以下内容: 什么是流(stream) 响应式流(Reactive Streams)的倡议是什么,以及规范和Java API 响应式流在JDK 中的AP ...

  8. Java 面试知识点解析(四)——版本特性篇

    前言: 在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Java 知识点进行复习和学习一番,大 ...

  9. 一文助您成为Java.Net双平台高手

    写在前面:本文乃标题党,不是月经贴,侧重于Web开发差异,或细节或概述,若有不对之处,还请各位读者本着友好互助的心态批评指正.由于博客园中.Neter较多(个人感觉),因此本文也可以作为.Neter到 ...

随机推荐

  1. Swift中的闭包(Closure)[转]

    闭包在Swift中非常有用.通俗的解释就是一个Int类型里存储着一个整数,一个String类型包含着一串字符,同样,闭包是一个包含着函数的类型.有了闭包,你就可以处理很多在一些古老的语言中不能处理的事 ...

  2. Object-C中 - self 和super 的含义

    //super:父类         //self:自己              //自己理解         //以MobilePhone为例,父类为NSObject         //在类方法 ...

  3. hdu 4888 最大流慢板

    http://acm.hdu.edu.cn/showproblem.php?pid=4888 添加一个源点与汇点,建图如下: 1. 源点 -> 每一行对应的点,流量限制为该行的和 2. 每一行对 ...

  4. iterm2 学习笔记

    itrem 笔记 选中即复制,有两种方式. 在新Tab中自动使用前一Tab路径,该怎么用? 系统热键:option+space 自动完成:输入打头几个字母,然后输入command+“;” iterm2 ...

  5. 软件工程作业 - 实现WC功能(java)

    项目地址:https://github.com/yogurt1998/WordCount 要求 基本要求 -c 统计文件字符数(实现) -w 统计文件单词数(实现) -l 统计文件行数(实现) 扩展功 ...

  6. Delphi Dll 动态调用例子(2)

    http://zhidao.baidu.com/question/157196792.html delphi动态调用DLL 写了个1.dll内容如下 library Project2; uses Sy ...

  7. 创建TFS备份计划失败,错误提示:TF400997

    问题描述 在一个TFS 2018 + SQL Server 2017的环境中,从TFS控制台中配置备份计划时,系统提示错误TF400997,需要授予数据库服务账户sqlservice@domain.c ...

  8. linux系统编程之信号(一):中断与信号

    一,什么是中断? 1.中断的基本概念 中断是指计算机在执行期间,系统内发生任何非寻常的或非预期的急需处理事件,使得CPU暂时中断当前正在执行的程序而转去执行相应的事件处理程序,待处理完毕后又返回原来被 ...

  9. System.IO.FileLoadException:“混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集。”

    解决方案: 在app.config新增如下配置节: <?xml version="1.0"?> <configuration> <startup us ...

  10. DataAnnotations 验证

    转自:http://blog.sina.com.cn/s/blog_c21a857b0102wcus.html 常用的 DataAnnotations 1.Required :属性值必须非空或者不能只 ...