精华内容
下载资源
问答
  • 构造函数可以有返回值吗

    千次阅读 2012-06-10 12:27:59
    给你一段构造方法的定义和作用,也许你就能明白了。解决问题的方式很多,你可以通过其他方式去实现你的需求,没什么什么解决不了的问题的~ =================== 1. 构造方法的特征 • 它具有与类相同的...
    给你一段构造方法的定义和作用,也许你就能明白了。解决问题的方式有很多,你可以通过其他方式去实现你的需求,没什么什么解决不了的问题的~
    
    ===================
    1. 构造方法的特征 
    
    • 它具有与类相同的名称; 
    • 它不含返回值; 
    • 它不能在方法中用 return 语句返回一个值; 
    • 当自定义了构造方法后,编译器将不再自动创建不带参数的构造方法 。 
    • 在构造方法里不含返回值的概念是不同于 “void” 的,在定义构造方法时加了 “void” ,结果这个方法就不再被自动调用了。
    
    
    
    2. 构造方法的作用:
    
    当一个类的实例对象刚产生时,这个类的构造方法就会被自动调用,我们可以在这个方法中加入要完成初始化工作的代码。
    
    
    摘自:http://zhidao.baidu.com/question/47196244.html
    展开全文
  • 众所周知,在java里是不能给构造函数写返回值的,如果在低版本的编译器定义一个构造器写上...构造函数有返回值吗 写一段代码测试一下: publicclassTest{ publicTest(){ } publicstaticvoidmain(String[]args){ ...

    众所周知,在java里是不能给构造函数写返回值的,如果在低版本的编译器定义一个构造器写上返回值可能会报错,高版本里面他就是一个普通的方法。
    可是如果构造函数没有返回值,那么比如Test t = new Test()我们new一个对象的时候是怎么赋值的呢?

    构造函数有返回值吗

    写一段代码测试一下:

    public class Test {
        public Test() {
           
        }
    
        public static void main(String[] args) {
            Test t = new Test();
        }
    }
    

    反编译一下看看:

     Code:
           0: new           #5 // class com/irving/utils/baidu/Test
           3: dup
           4: invokespecial #6 // Method "<init>":()V
           7: astore_1
           8: return
    

    从反编译的结果看 4: invokespecial #7 // Method “init”: ()V,调用构造函数,V代表void无返回值,那么init代表什么含义?

    我在书里找到这样一段话:

    在 Java 虚拟机层面上,Java 语言中的构造函数是以一个名为init的特殊实例初始化方法的形式出现的,init这个方法名称是由编译器命名的,因为它并非一个合法的 Java 方法名字,不可能通过程序编码的方式实现。实例初始化方法只能在实例的初始化期间,通过 Java 虚拟机的 invokespecial 指令来调用, 只有在实例正在构造的时候,实例初始化方法才可以被调用访问。

    一个类或者接口最多可以包含不超过一个类或接口的初始化方法,类或者接口就是通过这个方法完成初始化的。这个方法是一个不包含参数的静态方法,名为clinit。这个名字也是由编译器命名的,因为它并非一个合法的 Java 方法名字,不可能通过程序编码的方式实现。类或接口的初始化方法由 Java 虚拟机自身隐式调用,没有任何虚拟机字节码指令可以调用这个方法,只有在类的初始化阶段中会被虚拟机自身调用。

    init代表着虚拟机调用构造函数,现在情况很明显,构造函数返回类型是void,那么它究竟是怎么赋值的呢?

    赋值探究

    我们明白一点,方法的调用过程就是栈帧入栈和出栈的过程,栈帧随着方法的调用创建,方法结束销毁。栈帧的内部包含局部变量表、操作数栈、动态链接等。

    局部变量表表示方法调用时候的参数传递,当一个实例方法被调用的时候,第0个局部变量存储了当前实例方法所在对象的引用(this),后续的其他参数传递至1到N的连续位置。

    操作数栈用来准备方法调用的参数和返回结果。

    gzh_58185da0.png

    以上面测试代码的方法来看Test t = new Test() 的调用过程:

    1. new 创建Test对象,并将其引用值压入操作数栈顶
    2. dup 复制栈顶数值并将复制值压入栈顶
    3. invokespecial 使用dup复制的引用并用来初始化,此时栈顶应该只有new创建的原始引用
    4. astore_1 将new创建的引用存入局部变量表索引为1的位置
    5. return 方法正常返回

    gzh_c5d39ec3.png

    从这个过程我们已经看出来了,整个过程最后我们最终拿到了new之后创建的对象引用,并且保存到局部变量表中,可以供我们继续使用。

    关注公众号:java宝典
    a

    展开全文
  • “Java的构造方法到底还是没有返回值?” 当我看到这个问题的时候,我首先的反应是“Java的构造方法是没有返回值的”,随后我也便在网上搜索了一番,发现确实是持有两种截然不同观点的人都大有人在。于是我便开始...

    前言

    最近,偶然在网上看到有人在问:

    “Java的构造方法到底有还是没有返回值?”

    当我看到这个问题的时候,我首先的反应是“Java的构造方法是没有返回值的”,随后我也便在网上搜索了一番,发现确实是持有两种截然不同观点的人都大有人在。于是我便开始想,一个如此基本的问题,应该是大家早都“统一口径”了才对啊,毕竟Java已经是一个拥有24岁高龄的语言了。伴随着这种疑问,我开始了对这个问题的调研。

    1、调研

    对于Java基础的问题,最好的方法当然还是去官方的资料中去寻找。于是找到了Java语言规范的文档(Java8版本)。在标砖的语言规范中找到了一些线索,如下:

    • 在 8.2 Class Memebers章节中,规定了类的成员的来源继承自父类、继承自父接口、自身定义这3个来源,同时里面写到了这样的内容:

    Constructors, static initializers, and instance initializers are not members and therefore are not inherited.
    构造方法,静态初始化器,对象初始化器,都不是类的成员,因此它们也不可以被子类继承。

    • 在 8.8 Constructor Declarations 章节中,关于构造方法的定义有以下说明:

    a constructor declaration looks just like a method declaration that has no result
    一个 constructor 的定义就像是一个没有返回值的 method 的定义。

    emm… 在调研之后,恍然大悟,终于意识到了问题所在:

    这完全是一个英文转中文的翻译问题。

    从官方的文档中,我们能够发现,对于Java中的类成员是很明确的有三种:

    • Filed:成员变量
    • Method:普通方法
    • Type:内部定义的其他类型,如内部接口、内部类等

    而 Constructor 则是负责对一个对象进行初始化的,会在对象创建完成后由系统执行,它本身并不是类的成员,更不是一个“方法”,Constructor 的中文应该是构造器更合适。

    构造方法是:Constructor,成员方法是:Method

    也就是说,它们两个是两个平等的概念,而不是包含的关系。

    回过头来,既然Constructor 都不是个“方法”,那就没有返回值这个问题了?毕竟返回值是”方法“才有的特性。

    所以,这个本质问题就是把Constructor翻译成 构造方法是不合适的。想来这个翻译应该是受到了C++的影响。


    2、虚拟机层面

    上面分析了语言方面的原因,接下来稍微深入下,看下Java虚拟机层面ConstructorMethod的区别。

    构造器在字节码层面,是对应于一个名字为 的代码块,由编译器去生成,会在对象创建完成后需要初始化的时候进行执行。

    两者的执行在虚拟机层面也是有区分的,它们会使用不同的虚拟机指令来执行,对应的虚拟机指令:

    • Constructor:使用invokespecial 指令来执行
    • Method: 使用 invokevirtual 指令类执行

    3、构造“器”or构造“方法”

    // 构造方法的声明,就像是一个没有返回值的方法声明。
    a constructor declaration looks just like a method declaration that has no result,按照这个说法来说,应该认为构造方法是没有返回值的。而且请注意,构造方法 “就像是” 一个没有返回值的方法声明(注意,这里用了一个”“)。

    其次,如果往底层深究,假设有以下代码:

    package footest;
    
    public class Test {
    	private void foo(){
            String s = new String("Hello World");
            System.out.print(s);
    	}
    }
    
    • new 关键词对应于JVM中的 new指令,new指令会在堆内存中创建一个String 类型的对象(假设新创建的对象叫A),并把它的引用放在当前的栈顶;

    • JVM调用String类对应的构造方法进行初始化;取出栈顶的值,并将它放在本地变量表中 s对应的位置(完成赋值);

    • 所有的这些,都是根据Java语言规范来的,按照https://docs.oracle.com/javase/specs/jls/se12/html/jls-15.html#jls-15.9里面规定的,new关键字对应的是一个 Class Instance Creation Expressions(类示例化表达式),这个 类实例化表达式是用来创建对象的,而构造方法正式在类创建的期间被执行用于对象初始化的,只有在构造方法执行完了,类示例化表达式才算是完成了。

    所以,这其实这个问题有很大一部分是翻译的问题。

    因为“构造方法”这个中文翻译给太容易让人以为它是一个“成员方法”了。

    但是,其实不然,构造方法在Java语言规范里面叫 “Constructor” ,并不是一个成员方法(成员方法叫 Method),其实应该叫 “构造器”更合适。

    所以,这其实就是个翻译问题了,因为所谓的“构造方法(Constructot)”其实也不是一个“方法(Method)”,那么它自然就没有返回值不返回值的说法了。破除了翻译带来的问题之后,再来看这个问题,你还会问“java中构造器是否有返回值吗?


    注:此文章来自于知乎,链接如下:

    https://jiakaiyang.com/2020/03/28/java-is-constructor-a-method/#more

    https://www.zhihu.com/question/335196523/answer/751020648

    展开全文
  • 详解java的构造方法

    2017-09-22 15:29:00
    1.构造方法有返回值吗? 没有。构造方法没有任何返回类型,也不允许是void。比如: Java代码 publicclassTest{  //这不是构造函数! publicvoidTest(){ System.out.println("voidTest()"); } public...

    关于java的构造方法有几个简单的问题:

    1.构造方法有返回值吗?

         没有。构造方法没有任何返回类型,也不允许是void。比如:

    Java代码  

    1. public class Test {   
    2.  //这不是构造函数!   
    3. public void Test() {   
    4. System.out.println("void Test()");   
    5. }   
    6. public static void main(String[] args) {   
    7. Test test = new Test();   
    8. test.Test();   
    9. }   
    10. }   

     

     

     

     

          这里我们定义了一个返回类型为void的Test()方法,有了返回类型void,它就不是构造方法了。

     

         Test test = new Test();

         有人用上面的表达式来说明构造方法返回对象引用,这是明显错误的。new关键字有两个作用。一是分配内存,

    创建对象。二是调用构造方法,完成对象的初始化工作。完成这两步之后,才算创建了一个完整的Java对象。我们

    可以用Test test = new Test();的反编译代码来说明这个问题:

    0:    new    #5; //class Test

    3:    dup

    4:    invokespecial    #6; //Method "":()V

    7:    astore_1

          原表达式被编译成四条bytecode指令。

    new指令负责根据参数分配内存并创建Test对象,然后将新创建对象的引用置于栈顶。

    dup指令复制栈顶的内容,记住,此时栈最顶端的两个单元都是新创建对象的引用。

    接着是调用初始化方法,该方法是由构造方法编译而来,栈顶的引用作为此方法的参数消耗了。通过调用初始化方法完成

    对象的创建过程。这里注意一下初始化方法Method "":()V,它是void类型的。

    最后的astore_1指令将栈顶的对象引用赋给局部变量(前面说了,dup之后栈顶两个引用,一个给初始化方法吃掉了,一个留给astore_1操作用),也就是执行赋值操作。

         因此,得到的引用是new指令的结果,不是构造方法的返回值。

         有一点需要注意:new指令创建对象,同时使对象的各个字段得到其默认值,比如整数为0,浮点数为0.0,引用为null,boolean为false等。也就是说在构造方法执行之前,各个字段都有默认值了。这一点我们在第三条继续说明。

         通过上面说明,我们明确了构造方法的职能(初始化new指令创建的对象,得到一个状态合法的对象,完成对象的

    创建过程)。任何类都有构造方法,但是new指令只能创建非抽象类的对象。理解了这一点,也就不要再问"抽象类也有构造方法,为什么不能创建对象"之类的问题了。

     

    2.构造方法是静态的?

          错误。

          这是《Thinking In Java》中的一个观点。书里有一段:

    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.

    java编程思想》中文第四版96页:

    总结一下对象的创建过程,假设有个名为Dog的类:

    1.即使没有显示地使用static关键字,构造器实际上也是静态方法。因此,当首次创建类型为Dog的对象时(构造器可以看成

    是静态方法),或者Dog类的静态方法/静态域首次被访问时,Java解释器必须查找类路径,以定位Dog.class文件。

     

         这里我并没有看明白作者为什么说构造器实际上是静态方法。但是我们知道,静态方法是不能使用this的。因此,"构造器实际上也是静态方法"这点很好否定。看下面例子:

     

    Java代码  

    1. public class Test {   
    2. public Test() {   
    3. this.test2();   
    4. }   
    5. public static void test(){   
    6. this.test2();   
    7. }   
    8. public static void test2(){   
    9. }  
    10. }   

     

     

       test方法编译错误,因为静态方法中不能使用非静态的this,而构造方法使用this是没有问题的。

     

          如果有C++经验的话,可以类比一下。C++里的new操作符有两个作用,调用operator new()来分配内存,然后调用构造函数来完成初始化。

         而这里的operator new()是隐式静态的。参考《C++程序设计语言(特别版)》中文版的374页:

    比如这个例子:

    Cpp代码  

    1. class Employee{  
    2. //...   
    3. public:   
    4. //....   
    5. void* operator new(size_t);   
    6. void operator delete(void* ,size_t);   
    7. }   

     

         成员operator new()和operator delete()默认为static成员,因为它们没有this指针,也不会修改任何对象。它们将提供一些存储,供构造函数去初始化,而后由析构函数去清理。

      类比可知,静态的是负责分配内存的工具,而不是构造函数。 不知道《Thinking In Java》的作者是不是把这点弄混了?

     

    3.父类的构造方法中调用被子类重写的方法有多态现象。

         这句话很绕,直接看例子:

    Java代码  

    1. class Father{     
    2. private int i = 5;     
    3. public Father() {     
    4. System.out.println("Father's i is " + this.i);     
    5. test();     
    6. }     
    7. public void test(){     
    8. System.out.println(this.i);     
    9. }     
    10. }     
    11. class Son extends Father{     
    12. private int i = 55;     
    13. public Son() {     
    14. System.out.println("Son's i is " + this.i);     
    15. }     
    16. @Override    
    17. public void test() {     
    18. System.out.println(this.i);     
    19. }     
    20. }     
    21. public class Test {     
    22. public static void main(String[] args) {     
    23. new Son();     
    24. }     
    25. }   

         

     

     

     结果是:

    Father's i is 5
    0
    Son's i is 55

         结合第一点,构造方法调用之前,首先是new指令创建了一个对象,并将各个成员初始化为其默认值。下面看构造方法的调用过程。

         子类构造方法会调用父类构造方法,父类构造方法首先打印Father's i is 5。然后调用test()方法,注意,我们创建的是Son类的对象,所以test()方法调用的是Son类定义的test()方法,也就是说发生了多态。我们再去看Son类中test方法的实现,就是简单的输出this.i,为什么是0呢,别忘了我们还没有执行子类的构造方法啊,所以此时子类的i还是new指令初始化得到的0。好,test()方法执行完了,总算回到子类构造方法继续执行,先把i赋值为55,下面的输出语句Son's i is 55也就不难理解了。

        在构造方法中调用方法要特别注意这种多态现象。

     

        这种现象和c++里的现象是不同的。在C++中,如果在父类的构造函数中调用虚方法的话,调用的是父类定义的版本,不会发生多态现象。但一个有趣的现象是,C++的经典书籍和Java的经典书籍竟然都建议不要在构造方法里面调用多态方法,因为现象并不是你期待的!这就奇怪了,难道C++程序员和Java程序员天生就有相反的期待吗?

    转载于:https://www.cnblogs.com/taiyuanzhongruan/p/7575170.html

    展开全文
  • java的构造方法

    2012-04-10 19:05:00
    1.构造方法有返回值吗? 没有。构造方法没有任何返回类型,也不允许是void。比如: Java代码 publicclassTest{  //这不是构造函数! publicvoidTest(){ System.out.println("voidTe...
  • java中的构造方法

    千次阅读 2009-10-10 00:24:00
    构造方法有返回值吗? 没有。构造方法没有任何返回类型,也不允许是void。比如: public class Test { //这不是构造函数! public void Test() { System.out.println("void Test()"); } public static vo
  • 构造方法有返回值吗?  没有。构造方法没有任何返回类型,也不允许是void。比如:  public class Test {  //这不是构造函数!  public void Test() {  System.out.println("void Test()");  }  public...
  • 1.构造方法有返回值吗?  没有。构造方法没有任何返回类型,也不允许是void。比如: Java代码 public class Test { //这不是构造函数! public void Test() { System.
  • 1.构造方法有返回值吗?  没有。构造方法没有任何返回类型,也不允许是void。比如: public class Test {  //这不是构造函数! public void Test() { System.out.println("void Test()"); ...
  • ###前言 众所周知,在Java里是不能给构造函数写返回值的,如果在低版本的编译器...构造函数有返回值吗 写一段代码测试一下: public class Test { public Test() { } public static void main(String[] args) { T
  • 构造方法的特性 1.名字与类名相同。 2.没有返回值,但不能用 void 声明构造函数。 3.生成类的对象时自动执行,无需调用。 若一个类没有声明构造方法...因为一个类即使没有声明构造方法也会默认的无参构造方法。 ...
  • 构造方法

    2019-03-18 08:46:00
    1、构造方法的格式是什么?哪些注意事项? 答:修饰符 构造方法名(参数列表){ } 注意事项: 一般情况下没有返回值构造方法名必须与类名一致 构造方法体:this可以在构造方法之间进行调用 this()...
  • 构造方法的作用

    2017-06-03 15:02:16
    构造方法有什么作用? 在我们的java程序中,经常会需要创建类,在创建类时可以定义构造方法,当然也可以不定义构造方法,如果没有构造方法,会默认提供一个无参的构造方法。那么你知道构造方法的作用吗? 答:构造...
  • 每一个类都有构造方法构造方法的方法名必须要和类名一致,并且没得返回值类型,void都不要写,不能返回一个具体的值,如果不写构造方法,Java编辑器会为这个类创建一个默认的构造方法。 格式: 修饰符 返回值类型 ...
  • // 方法 [访问修饰符] 返回值类型 方法名(参数列表){ 代码; return 具体的返回值; } 复制代码 参数传递: 基本数据类型做参数时,传递的是值,不能出方法的范围 引用数据类型做参数时,传递的是地址,可以...
  • 构造方法和this的使用

    2021-03-03 17:04:26
    * 构造方法:他的方法名是和类名相同的,且没有返回值。 * 提出问题:一个对象的产生,分为几步,它是如何产生的? *1:为对象分配内存 * 2:调用合适的构造方法(意味着构造方法不止一个) *1.当没有提供构造...
  • 我 :((⊙o⊙)… ,构造方法有什么聊的,对象的new不是一直在用吗?) 构造方法是一种特殊的方法,它是一个与类同名且没有返回值类型的方法。对象的创建就是通过构造方法来完成,其功能主要是完成对象的初始化。当...
  • 众所周知,在java里是不能给构造函数写返回值的,如果在低版本的编译器定义一...构造函数有返回值吗 写一段代码测试一下: public class Test { public Test() { } public static void main(String[] args) {
  • 构造器是方法名和类名相同,并且没有返回值的特殊方法,可以使用的关键字public, protected &... //构造方法 public Constructor(){ } //实例方法 public void Constructor(){ System.out.prin...
  • 构造函数

    2017-05-22 11:50:00
    构造函数有返回值怎么办?构造函数能当普通函数调用吗? 以下是我的一些理解,理解错误的地方恳请大家帮忙指正,谢谢! thisthis永远指向当前正在被执行的函数或方法的owner。例如: ? 1 2 3 4...
  • 当为构造器声明添加任何返回值类型声明,或者添加void声明该构造器没有返回值时,编译器并不会提示这个构造错误,只是系统会把这个所谓的“构造器”当成普通方法处理。这个时候初始化类实例时系统会调用默认的无...
  • 构造函数有返回值怎么办? 构造函数能当普通函数调用吗? 以下是我的一些理解,理解错误的地方恳请大家帮忙指正,谢谢! this this永远指向当前正在被执行的函数或方法的owner。例如: function te...
  • 构造函数有返回值怎么办?构造函数能当普通函数调用吗? thisthis永远指向当前正在被执行的函数或方法的owner。例如: 1 2 3 4 5 function test(){ console.log(this); } test(); ...
  • 构造函数有返回值怎么办? 构造函数能当普通函数调用吗?以下是我的一些理解,理解错误的地方恳请大家帮忙指正,谢谢!this this永远指向当前正在被执行的函数或方法的owner。例如:function test(){ console....

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 155
精华内容 62
关键字:

构造方法有返回值吗