Thinking in java 中说“即使没有显式的使用static关键字,构造器实际上也是静态方法。”
但在静态方法中不能调用非静态变量,可构造器中可以。这是怎么回事?Thinking in java写错了?还是其他神马原因?
求讲解!

解决方案 »

  1.   

    我的理解:
    构造器不是方法,不能用static修饰。它也不是变量,不能用一般的成员变量调用规则去对它套用。很特殊的存在。
    《Thinking in Java》中说那句话,可能有如下原因:
    1、中文翻译有误;
    2、静态,作者可能理解为“属于类的”,构造器也确实属于类的,非某个对象的引用调用它;
    3、构造器如果修饰为私有,如果别的类想创建该类的对象,必须使用静态工厂方法,这个静态工厂方法是静态的方法,也有构造器创建对象的功能,作者讲它比喻为构造器。个人理解
      

  2.   

    翻译没错,原书的问题。
    Even though it doesn’t explicitly use the static keyword, the constructor is actually a static method. So the first time an object of type Dog is created, or the first time a static method or static field of class Dog is accessed, the Java interpreter must
    locate Dog.class, which it does by searching through the classpath. 
    感觉前言不搭后语的。看这本书要慎重,小心一些误导性的东东。
      

  3.   

    构造器是“初始化”对象的,分配对象new表达式负责。所以先分配对象所需内存,再默认初始化,再调用构造器。
    跟鸡蛋问题无关。
      

  4.   

    此书已历四版,相信如此明显的错误是不会犯的。
    因为我找不到这段话在书地哪个位置,只能根据这段英文作下理解:
    作者这里着重讲构造器是怎样起作用的,而非讲构造器需要注意什么内容。为了达到这一目的,将构造器比喻成静态,这点从他将“创建对象”和静态方法、静态语块并列起来可知。这个“actually”用得很诡异,如果想说构造器就是静态方法,actually应该换为exactly。
      

  5.   

    构造器方法与其它的方法有一个重要的不同之处。构造器总是伴随着new操作符的执行而被调用,而不能对一个已经存在的对象调用构造器来达到重新设置实例域的目的。例如:
    public class Person
    {
         String name;
         Person(String n)
         {
             name = n;
         }
         public static void show()
         {
            //xxxxxxxx
         }
    }假如我new出一个对象person
    那么你就不能这么调用:person.Person("Java");//Error
    因为构造器总是伴随着new操作符一起才能调用,
    而含有static的方法调用却可以这样:   person.show();//OK也就是说,构造器和静态方法不是一条路的,他们两不具有可比性,不要把静态方法的一些性质强加到构造器上。嗯,这就是我的理解,希望对LZ有所帮助。
      

  6.   

    学习了。刚才楼上说了一个问题。就1.是那构造器是什么时候 谁来调用的呢?(构造器到底是不是static的)
    2.和调用一般的方法有何区别?
      

  7.   

    看了一下原版英文,大概翻译是
    即使没有显式的使用static关键字,构造器实际上也是静态方法。因此,第一次一个类型为Dog的对象被创建,或者第一次Dog类的静态方法或静态属性被访问时,java解释器就必须加载Dog.class,它是通过查找classpath而来的
    所以感觉作者对static的理解是从类加载的角度上来考虑的,其实我们知道,一个类被使用到的时候,JVM就会加载该class,所以,即使不创建,也就是说没有new,只要引用到了该类,JVM应该就会自动加载class了,比如
    Dog dog; //不需要Dog dog = new Dog();
    或者
    Class c = Dog.class; 
    等等,JVM都会查找classpath去加载Dog.class
    所以个人感觉这段话有点问题,构造器是个特殊的方法,和new这个特殊操作符一起使用(new操作符会产生一个new指令),但是不至于是个static方法(就看对static怎么理解),可以通过反编译查看构造器的代码,第一步一般都是aload_0,也就是把this指针压栈,按照static的解释,static方法是不需要也不能直接访问这个this的。所以构造器是static的说法不成立。纯属个人看法