今天在看《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. ajax 实现订单商品数量的增减及订单的删除进行异步更新界面

    [转载]https://blog.csdn.net/luliuying_01/article/details/78177617?locationNum=8&fps=1 由于在做答辩项目,做到购 ...

  2. python TCP协议详解 三次握手四次挥手和11种状态

    11种状态解析 LISTEN  --------------------  等待从任何远端TCP 和端口的连接请求. SYN_SENT  ---------------  发送完一个连接请求后等待一个 ...

  3. bacula快速部署

    快速部署: Server端:DD.SD.Monitor.Console均部署在Server上Client端:FD Server端部署:上传事先下载的源码包 tar xvf bacula-9.2.0.t ...

  4. ES5的数组方法

    参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array Array.prot ...

  5. 如何在Python中显式释放内存?

    根据Python官方文档,您可以强制垃圾收集器释放未引用的内存gc.collect().例: import gc gc.collect() 所属网站分类: python高级 > 综合&其 ...

  6. 大数据学习——mapreduce程序单词统计

    项目结构 pom.xml文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&q ...

  7. sql模糊查询,解除绑定的单号

    --610007570320-610007571319 1000张 delete from (select t.* from (select t1.bill_code, t1.bind_code, t ...

  8. python--如何在线上环境优雅的修改配置文件?

    1.如何在线上环境优雅的修改配置文件? 原配置文件 #原配置文件 global log 127.0.0.1 local2 daemon maxconn 256 log 127.0.0.1 local2 ...

  9. 局部二值模式(Local Binary Patterns)纹理灰度与旋转不变性

    Multiresolution Gray Scale and Rotation Invariant Texture Classification with Local Binary Patterns, ...

  10. HUD-1559 最大子矩阵,dp模拟

    最大子矩阵                                                                                               ...