zoukankan      html  css  js  c++  java
  • 【Java】构造方法和匿名对象

    前言

    在编写程序时不安全的初始化会导致程序发生发生重大错误。为了使程序可以被安全地初始化,C++引入了构造器(也可以成为构造方法)的概念,这是一个在创建对象时被自动调用的特殊方法。Java中也采用了构造器,并且提供了“垃圾回收器”。对不再使用的内存资源,垃圾回收器能自动将其释放。本文下面主要介绍Java的构造方法以及匿名对象。

    构造方法的定义语法与调用时机

    构造方法的定义语法及访问权限

    构造方法是在创建对象时被编译器自动调用,所以编译器应该知道构造方法的名字然后去调用它,为构造方法任意取名都可能会与类的某个成员冲突。于是Java采用了同C++中一样的方法:构造方法采用与类相同的名称

    构造方法一般定义为如下三种方式:

    class Student{
      public Student(){     //①
        ...
      }
      ...
    }
    class Student{
      Student(){      //②
        ...
      }
      ...
    }
    class Student{
      private Student(){    //③
        ...
      }
      ...
    }
    

    以上三种构造方式涉及到了访问权限的问题:

    第①种方式,构造方法采用了public修饰表示该类的对象是可以被不同包(package)的其他类创建。

    第②种方式,默认为包访问属性,仅限于同包的类可以创建该类的对象。

    第③种方式,使用private修饰使得构造方法对外不可见,无法在外部调用该类的构造器创建其实例。一般通过工厂模式创建该类实例。

    以上列举了三种访问权限访问修饰符,如果学过C++那旧还知道一种没有出现的访问权限修饰符就是protected。该修饰符表示本包中的类可访问,不同包中的子类可以访问。

    对包做一个解释:包类似于电脑中的文件夹,文件多了需要存于不同文件夹中方便管理,同样如此,类多了就需要放在不同的包里面方便管理,同时也避免了命名冲突问题。

    总结访问权限修饰符的可访问性:

    范围 private default(默认包访问) protected public
    同一个类 O O O O
    同一个包中的子类 X O O O
    同一个包中的其他类 X O O O
    不同包中的子类 X X O O
    不同包中的非子类 X X X O

    构造方法的调用时机(创建对象的初始化顺序)

    前面一直在说构造方法的调用是在类创建时,与普通方法不同,构造方法在实例化新对象(使用new开辟空间后)调用一次。普通方法在对象被实例化后可以调用多次。

    由于对初始化有不同的需求,因此构造方法也可重载的。

    下面跟踪一下构造方法被调用的过程:

    class Person{
    	  private long pid=123456789;
    	  public Person(){
    		  System.out.println("Person()");
    	  }
    	  public Person(long pid){
    		System.out.println("Person(long pid)");
    		System.out.println("在使用传进来的pid赋值前:pid:"+this.pid);
    	    this.pid = pid;
    	    System.out.println("在使用传进来的pid赋值后:pid:"+this.pid);
    	  }
    }
    public class Student extends Person{   //extends 实现继承关系
      private String name;
      private int age=0;
      public Student(){
    	  System.out.println("Student()");
      }
      public Student(long pid, String name, int age){
        super(pid);			//调用父类的构造函数一定要写在最前面不然会报错
        System.out.println("Student(long pid, String name, int age)");
        this.name = name;
        this.age = age;
      }
      public getName(){
        return name;
      }
      public static void main(String[] args){
        Student stu1 = new Student();
        Student stu2 = new Student(123456,"Sakura",20);
      }
    }
    /*
    output:
    Person()
    Student()
    Person(long pid)
    在使用传进来的pid赋值前:pid:123456789
    在使用传进来的pid赋值后:pid:123456
    Student(long pid, String name, int age)
    */
    

    可以输出结果看出Java中的初始化顺序如下:

    • 在任何其他事情发生之前,首先会将分配给对象的存储空间初始化成二进制零。
    • 调用基类的构造函数。
    • 按照声明顺序调用属性的初始化方法。在Person中先将pid赋值为1234556789然后在返回到构造函数中将123456赋值给pid。
    • 调用导出类的构造函数。若是Student中属性有给定初始值,那么依旧如第三步后再进入构造函数进行其他初始化操作。

    匿名对象

    什么是匿名对象?

    我们来看一步就创建对象的语法:

    ①类名称 ②对象名称 = ③new ④类名称()
    
    1. ①:规定了对象的类型
    2. ②:对象的名字,唯一标识对象
    3. ③:开辟新的堆内存空间,存储对象的内容
    4. ④:调用构造方法初始化对象

    上面的这条语句在内存中开辟了两个空间,一个栈空间存储引用变量对象名称,一个使用new开辟的堆空间用于存储对象内容。

    对象名称指向了在对堆中的对象,于是我们可以使用对象名称去操作对象

    若是我们只有"new 类名称();"这部分的话,那就是只是在堆中开辟了一个空间来保存对象信息,没有栈去指向它。也就是这个空间是没有名字的。所以简单来说,没有栈中引用指向的对象就叫做匿名对象

    匿名对象的使用

    new Student(123456,"Sakura",20).getName();
    

    由此就创建了一个匿名对象,可以向操作具名对象一样操作它。
    由于没有引用变量指向匿名对象,所以只能使用一次,然后就会成为垃圾对象等待被GC回收,

    小结

    总结了Java中构造方法的定义和作用(为了在类对象实例化时设置属性初始化)由此涉及到到类访问权限,然后对类访问权限做了一个小结,以及Java程序初始化的顺序。最后介绍了匿名对象,即没有栈中引用指向的对象。

    参考:

    [1] Eckel B. Java编程思想(第四版)[M]. 北京: 机械工业出版社, 2007

  • 相关阅读:
    Delphi XE5 android 蓝牙通讯传输
    Delphi XE5 android toast
    Delphi XE5 android openurl(转)
    Delphi XE5 如何设计并使用FireMonkeyStyle(转)
    Delphi XE5 android 捕获几个事件
    Delphi XE5 android listview
    Delphi XE5 android 黑屏的临时解决办法
    Delphi XE5 android popumenu
    Delphi XE5 android 获取网络状态
    Delphi XE5 android 获取电池电量
  • 原文地址:https://www.cnblogs.com/myworld7/p/9977000.html
Copyright © 2011-2022 走看看