今天在看《thinking in java》的时候,第四章提到了非法的前向引用,于是自己试了一下,书中的例子倒是一下就明白了,但是自己写的一个却怎么也不明白,于是上网问了一位前辈,终于明白啦!

这个是错误的代码:

class BB
{
static int a = 0 ;
public BB()
{
a++ ;
System.out.println("执行BB" + a) ;
} public void printA()
{
System.out.println("a= " + a) ;
}
} public class CC
{
static
{
a = new BB() ;
a.printA() ;    //报错说非法的前向引用
}
static BB a = new BB() ; public staic void main(String args[])
{
CC c = new CC() ;
}
}

  为什么我在static代码块中对a进行了初始化,仍然报错呢?

原因就涉及了java对于初始化过程中对成员变量的限制:

  成员变量a如果满足如下的4点,就必须在使用前必须对该成员变量进行声明

    1. 设定C为直接包含该成员变量的类或者接口
    2. 如果a出现在在C的或静态成员/非静态成员初始化 或者 C的静态或非静态代码块中
    3. 如果a不是 一个赋值不等式的左值
    4. 通过简单名称来访问

在我自己写的代码中,a.printA() ;出现的位置是CC的静态代码块中,通过简单名称直接访问(也就是直接使用a), 并且不是赋值不等式的左值,所以会报错“非法的前向引用”

这个是java语言规范中的原文代码(其中的中文是我自己的标注):

class UseBeforeDeclaration
{
static
{
x = 100;
// ok - assignment , 赋值表达式的左值
int y = x + 1;
// error - read before declaration , 赋值表达式的右值
int v = x = 3;
// ok - x at left hand side of assignment , 左值
int z = UseBeforeDeclaration.x * 2;
// ok - not accessed via simple name , 是通过类.静态变量 的形式访问, 而非直接简单访问 Object o = new Object()
{
void foo()
{
x++;
}
// ok - occurs in a different class , 不是CC的代码块或成员初始化中,而是在一个全新的内部类的函数中
{
x++;
}
// ok - occurs in a different class , 在一个内部类的代码块中, 和上一个类似
};
} {
j = 200;
// ok - assignment
j = j + 1;
// error - right hand side reads before declaration , 第二个右值
int k = j = j + 1;
// error - illegal forward reference to j , 第三个是右值
int n = j = 300;
// ok - j at left hand side of assignment , 左值
int h = j++;
// error - read before declaration , 右值, 并参与了自增运算
int l = this.j * 3;
// ok - not accessed via simple name 通过this.j进行访问, 非直接简单访问 Object o = new Object()
{
void foo()
{
j++;
}
// ok - occurs in a different class
{
j = j + 1;
}
// ok - occurs in a different class
};
} int w = x = 3;
// ok - x at left hand side of assignment
int p = x;
// ok - instance initializers may access static fields static int u =
(new Object()
{
int bar()
{
return x;
}
}).bar();
// ok - occurs in a different class static int x; int m = j = 4;
// ok - j at left hand side of assignment
int o =
(new Object()
{
int bar()
{
return j;
}
}).bar();
// ok - occurs in a different class
int j;
}

  //提问的原文地址: http://segmentfault.com/q/1010000002569214

  //这部分知识的java文档: http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.2.3

  //thinking in java笔记,如果有不对的地方,还望指正^_^

java 报错非法的前向引用的更多相关文章

  1. maven报错非法字符:\65279 错误

    开发中一个项目很早就报这个错,maven报错非法字符:\65279 错误,今天终于忍无可忍要解决它 :编译java文件的时候,有些java文件报非法字符 \65279错误,在网上找和很多 方法,也试了 ...

  2. 转:maven报错非法字符:\65279 错误

    开发中一个项目很早就报这个错,maven报错非法字符:\65279 错误,今天终于忍无可忍要解决它 :编译java文件的时候,有些java文件报非法字符 \65279错误,在网上找和很多 方法,也试了 ...

  3. 由ctf来看java报错的危害

    很多java报错在我们渗透的时候经常会被发现,但由于没什么用,危害比较低被忽略,开发也很不愿意修改. 但从纵深防御的角度来说,多个小问题的结合就会产生严重的问题.此次遇到的一个ctf题就是一个例子. ...

  4. [java报错]Could not instantiate listener XXXXXX

    写在开头的话: 兜兜转转,辞去了深圳的工作,回到了武汉,从事的居然一度是我最不想学的语言-java,曾经以为自己并不会java,但是上手之后,发现语言都是相通的,自己一度排斥学习java真的是不能再傻 ...

  5. java报错问题记录

    java.lang.NoSuchMethodError 运行时错误,再编译期一般不会出现这个问题.NoSuchMethodError中文意思是没有找到方法,遇到这个错误并不是说依赖的jar包.方法不存 ...

  6. Java报错--Unsupported major.minor version 52.0

    遇到一个Java相关的报错: ... java.lang.UnsupportedClassVersionError: ... : Unsupported major.minor version 52. ...

  7. 最近纠结致死的一个java报错java.net.SocketException: Connection reset 终于得到解决

    自从SEOTcs系统11月份24日更新了一下SEO得分算法以来,一直困扰我的一个问题出现了,java的数据job任务,在执行过程中会经常报以下的错误: “2011-12-03 18:00:32 Def ...

  8. cygwin下java报错“找不到或无法加载主类”的故障排除

    win7 下安装了java,命令行下可以正常运行,cygwin下报错:找不到或无法加载主类. 经排查发现是cygwin的~/.bash_profile中画蛇添足的配置了$CLASSPATH: JAVA ...

  9. java报错排解

    1.eclipse新安装第一次启动报错: Javawas started but returned exit code=13-- 这是由于JDK和eclipse和电脑的位数不一致所致,要么都为32位, ...

随机推荐

  1. margin塌陷和margin合并问题及解决方案

    margin塌陷 先举个例子 <style> body{ background-color:#000; } .wrapper{ width:200px; height:200px; bac ...

  2. 将中文库导入到ARM板子中以解决中文显示乱码的教程

    1.将中文字符集导入到ARM板子中的/usr/fonts/目录下 在这里我们使用的字符集为:DroidSansFallback.ttf 下载地址为:https://pan.baidu.com/s/1e ...

  3. jQuery的on绑定click和直接绑定click区别

    状况之外 在之前的公司并没有遇到这个问题,也就没有深究.直到自己换了现在的公司,刚来第二天就开始写别人写到一半的项目,很无奈,不是原生就是jquery,由于项目急,已经来不及切换框架重新布局,只能继续 ...

  4. Java学习之for循环打印菱形练习

    for循环语句是Java程序设计中非常有用的循环语句.一个for循环可以用来重复执行某条语句,直到某个条件得到满足.在Java 5新增的加强的foreach语法,也非常有用. 1. for语句 for ...

  5. 【02】使用Firebug查看和编辑HTML和CSS

    使用Firebug查看和编辑HTML和CSS 描述 在本章节的教程中,我们将讨论如何使用Firebug查看和编辑HTML和CSS. 使用Firebug查看和编辑HTML 在你要查看的元素上右击鼠标然后 ...

  6. python024 Python3 实例

    Python3 实例 以下实例在 Python3.4.3 版本下测试通过: Python Hello World 实例 Python 数字求和 Python 平方根 Python 二次方程 Pytho ...

  7. SQL Server 创建唯一约束sql语句

    SQL Server 创建唯一约束sql语句   语句示例:   在创建表是时同时创建, 创建id,name,sex三个字段的唯一索引 create table t1( id int primary ...

  8. Hihocoder #1067 : 最近公共祖先·二

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上上回说到,小Hi和小Ho用非常拙劣——或者说粗糙的手段山寨出了一个神奇的网站,这个网站可以计算出某两个人的所有共同祖先中 ...

  9. 【POJ3294】Life Forms(后缀数组,二分)

    题意: n<=100 len[i]<=1000 思路:这是一道论文题 ..]of longint; ch:..]of ansistring; n,n1,l,r,mid,last,i,j,m ...

  10. iOS url带中文下载时 报错解决方法

    问题描述:下载文件时, 请求带中文的URL的资源时,比如:http://s237.sznews.com/pic/2010/11/23/e4fa5794926548ac953a8a525a23b6f2/ ...