据说一半以上的java程序员会出错的题

大三即将结束,经过一段时间的较为系统的自学java, 突然看到一个自称一半以上的java程序员都会出错的程序尤为感兴趣。便深究了一番

程序代码如下:

  1. package com.longpo;
  • class

Person {

  • private

static Person person = new Person();

  • public

static int count1;

  • public

static int count2 = 5;

  • private

Person() {

  • count1++;
  • count2++;
  • }
  • public

static Person getInstance()

  • {
  • return

person;

  • }
  • }
  • public

class Testsingleton {

  • public

static void main(String[] args) {

  • Person person=Person.getInstance();
  • //可以用直接Person.count1
  • System.out.println("count1: "

+person.count1);

  • System.out.println("count2: "

+person.count2);

  • }
  • }

上面代码输出的结果是什么呢?

很容易让人觉得会输出1和6(从题目可知肯定不是这么简单),那时我猜答案应该是1和5,但说不出所以然。我把代码赋值到Eclipse下运行。得到

和我猜的一样,可是我完全不知道其原因。。于是就开始了谷歌求知之路,经过研究,ClassLoader渐渐映入我的眼帘。下面我来说说我认为的原因,有错误还望指导更正

类在执行之前会执行三个步骤:

1.类的加载:查找并加载类的二进制数据,把对应的class文件加载到内存

2.连接

2.1. 验证:确保被加载的类的正确性(主要防止恶心的class文件被加载)

2.2. 准备:为类的静态变量分配内存,并将其初始化为默认值

2.3. 解析:把类中的符合引用转换为直接引用

3.初始化:为类的静态变量赋予正确的初始值

发现其中步骤2.2和3提到了关键字静态变量,重点关注这两步,2.2的结果会导致为静态变量

person,count1,count2分配内存并赋值(默认值)

person=null;

count1=count2=0

到步骤3,初始化时会为静态变量赋予正确的值,那么什么时候才会进行初始化呢?接着

谷歌百度,得到:

所有的java虚拟机实现必须在每一个类或接口被java程序“首次主动使用

”时才初始化

java对类的使用方式分为:主动使用,被动使用

主动使用有六种:(除这6种外,其他都是被动使用)

1。创建类的实例

2。访问某个类或接口的静态变量或对该静态变量赋值

3。调用类的静态方法

4。反射

5。初始化类的子类

6。java虚拟机启动时被标注位启动类的类

懂了第三步(初始化),那么就可以来解释程序为什么输出1和5了,我画了一个图

现在应该明白了其中的原因了吧,为了检验是否真的明白,可以把代码再改为

  1. package

com.longpo;

  • class

Person {

  • public

static int count1;

  • public

static int count2 = 5;

  • private

static Person person = new Person();

  • private

Person() {

  • count1++;
  • count2++;
  • }
  • public

static Person getInstance()

  • {
  • return

person;

  • }
  • }
  • public

class Testsingleton {

  • public

static void main(String[] args) {

  • Person person=Person.getInstance();
  • //可以用直接Person.count1
  • System.out.println("count1: "

+person.count1);

  • System.out.println("count2: "

+person.count2);

  • }
  • }  ?

原文来自techfox技术论坛java社区 http://techfoxbbs.com/blog-1-3.html

时间: 2024-10-09 15:56:05

据说一半以上的java程序员会出错的题的相关文章

Java程序员精选高频面试笔试题全家桶,通往BAT必备法宝!《附赠PDF》

作为一名即将求职的程序员,面对一个可能跟近些年非常不同的 2019 年,你的就业机会和风口会出现在哪里?在这种新环境下,工作应该选择大厂还是小公司?已有几年工作经验的老兵,又应该如何保持和提升自身竞争力,转被动为主动? 最近这波互联网裁员浪潮下,许多朋友被裁之后几周内陆陆续续找到工作,但也有部分现在还在求职中,其中重要区别就是在于平时是否坚持积累和成长. 面对工作,与其选择满不情愿,最后收获痛苦煎熬和差强人意的结果,不如思考如何提升工作效率和自身能力,在工作中关注自身能力成长,并去刻意练习,想办

To Java程序员:切勿用普通for循环遍历LinkedList

ArrayList与LinkedList的普通for循环遍历 对于大部分Java程序员朋友们来说,可能平时使用得最多的List就是ArrayList,对于ArrayList的遍历,一般用如下写法: public static void main(String[] args) { List<Integer> arrayList = new ArrayList<Integer>(); for (int i = 0; i < 100; i++) arrayList.add(i);

做什么职业,也别做程序员,尤其是Java程序员

千万别做程序员,尤其别做Java这种门槛低,入门快的程序员(别跟我说Java搞精通了也很牛之类的,原因不解释,做5年以上就知道了),程序员本来就是我见过最坑爹的职业了...Java程序员更是,现在满地都是Java培训机构,不出3年,你就不值钱了,就像3年前的C++一样!而且Java贬值更快,因为他比c++简单多了,培训个3个月,直接上岗,你说你怎么保证自己是不可替换的?而且现在Java程序员的整体工资,已经有不断下降的趋势! 我就用我的亲身经历告诉你,你这个想转程序员的人:别做这行,因为你不知道

一个java程序员的真实经历

半路出家的老java程序员的一点感悟 我是一个老java程序员,现在基本告别编码时代了,当然我现在还在写代码,不是为了老板写了,是自己在创业.回想起这么多年的人生路,作为一名老程序员感慨颇多,尤其是作为一名半路出家的程序员,其中的滋味更是感慨万分.下面我就自己说说我的经历,也许会给未来码农一点启发. 首先讲讲我是怎么成为一个程序员的,这个还真要说说中国的教育.我们国家的这种应试教育一直受到很多人的诟病,有的指责扼杀了学生的创造力,有的指责培养出来的学生就像火腿厂生产的香肠,都是一个味毫无特点而言

To Java程序员:切勿用普通for循环遍历LinkedList(转)

ArrayList与LinkedList的普通for循环遍历 对于大部分Java程序员朋友们来说,可能平时使用得最多的List就是ArrayList,对于ArrayList的遍历,一般用如下写法: public static void main(String[] args) { List<Integer> arrayList = new ArrayList<Integer>(); for (int i = 0; i < 100; i++) arrayList.add(i);

工作了3年的JAVA程序员应该具备什么技能?(zhuan)

http://www.500d.me/article/5441.html **************************************** 来源:五百丁 作者:LZ2016-03-18 因为和同事有约定再加上LZ自己也喜欢做完一件事之后进行总结,因此有了这篇文章.这篇文章大部分内容都是面向整个程序员群体的,当然因为LZ本身是做Java开发的,因此有一部分内容也是专门面向咱们Java程序员的. 简单先说一下,LZ坐标杭州,13届本科毕业,算上年前在阿里巴巴B2B事业部的面试,一共有

做什么职业,也别做程序员,尤其是Java程序员(转载)

千万别做程序员,尤其别做Java这种门槛低,入门快的程序员(别跟我说Java搞精通了也很牛之类的,原因不解释,做5年以上就知道了),程序员本来就是我见过最坑爹的职业了...Java程序员更是,现在满地都是Java培训机构,不出3年,你就不值钱了,就像3年前的C++一样!而且Java贬值更快,因为他比c++简单多了,培训个3个月,直接上岗,你说你怎么保证自己是不可替换的?而且现在Java程序员的整体工资,已经有不断下降的趋势! 我就用我的亲身经历告诉你,你这个想转程序员的人:别做这行,因为你不知道

转载:java程序员如何拿到2万月薪

作者:匿名用户链接:https://www.zhihu.com/question/39890405/answer/83676977来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:匿名用户链接:https://www.zhihu.com/question/39890405/answer/83676977来源:知乎 ---------------------------------------------------------------我是分割线------

中软国际Java程序员笔试题

1.谈谈final, finally, finalize的区别. final:修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承.因此一个类不能既被声明为 abstract的,又被声明为final的.将变量或方法声明为final,可以保证它们在使用中不被改变.被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改.被声明为final的方法也同样只能使用,不能重载. finally:在异常处理时提供 finally 块来执行任何