如何正确的创建和销毁 Java 对象?

2023-03-21 10:32:25 浏览数 (3)

一、介绍

Java由Sun Microsystems发明并在1995年发布,是世界上使用最广泛的编程语言之一。Java是一个通用编程语言。由于它拥有功能强大的库、运行时、简单的语法、平台无关(Write Once, Run Anywhere - WORA)以及令人敬畏的社区从而吸引了很多的开发者。

本系列文章我们我们将会覆盖一些高级的Java概念,我们假设你对Java语言已经有一些基础知识。本系列文章并不是一个完整的参考,而是一个将您的Java技能提升到下一个级别的详细指南。

本系列文章中将会看到一些代码片段,在这些代码片段里面将会使用java 7的语法以及java 8的语法。另外,Java 8 系列教程全部整理好了,微信搜索Java技术栈在菜单栏阅读。

二、实例构造(Instance Construction)

Java是面向对象的编程语言,所以新实例(objects)的创建可能是它最重要的概念之一。在新的类实例中构造器(Constructors)扮演了非常核心的角色,Java对于构造器(Constructors)的定义提供了很多方案。

2.1 隐式(implicitly)构造器

Java允许定义无任何构造器的类,但是这并不意味着此类没有构造器。比如说,让我们看一下下面这个类。

代码语言:javascript复制
package com.javacodegeeks.advanced.construction;
public class NoConstructor {
}

此类没有构造器,但是Java编译器会隐式地(implicitly)生成一个构造器并且在使用new关键字创建新的类实例时会被调用。

代码语言:javascript复制
final NoConstructor noConstructorInstance = new NoConstructor();
2.2 无参构造器(Constructors without Arguments)

无参构造器是显式执行Java编译器工作的最简单的方法。

代码语言:javascript复制
package com.javacodegeeks.advanced.construction;
public class NoArgConstructor {
    public NoArgConstructor() {
        // Constructor body here
    }
}

在使用new关键字创建此类的新实例时会此构造器将会被调用。

代码语言:javascript复制
final NoArgConstructor noArgConstructor = new NoArgConstructor();
2.3 有参构造器(Constructors with Arguments)

有参构造器是参数化创建类实例的一个非常有意思和有用的方法。下面这个类定义了一个具有两个参数的构造器。

代码语言:javascript复制
package com.javacodegeeks.advanced.construction;
public class ConstructorWithArguments {
    public ConstructorWithArguments(final String arg1,final String arg2) {
        // Constructor body here
    }
}

在这种情况下,当使用new关键字创建类实例时,两个构造参数都必须提供。

代码语言:javascript复制
final ConstructorWithArguments constructorWithArguments = new ConstructorWithArguments( "arg1", "arg2" );

非常有意思的是,使用this关键字,构造器之间可以相互调用。这种连接构造函数的方式在作为减少代码重复方面是一个非常好的实践,并且从跟本上说这样做可以让一个类只有一个初始化入口点。接上例,我们添加一个只有一个参数的构造器。

代码语言:javascript复制
public ConstructorWithArguments(final String arg1) {
this(arg1, null);
}
2.4 初始化块(Initialization Blocks)

Java也提供了另外一种使用初始化块的方式实现初始化逻辑。这个特性很少使用但是非常有必要了解一下它的存在。

代码语言:javascript复制
package com.javacodegeeks.advanced.construction;
    public class InitializationBlock {
    {
        // initialization code here
    }
}

在某些情况下,初始化块可以弥补匿名无参构造器的缺陷。有一些特殊的类可能会有很多个初始化块并且他们会依次按照他们在代码中定义的顺序被调用,比如:

代码语言:javascript复制
package com.javacodegeeks.advanced.construction;
public class InitializationBlocks {
    {
        // initialization code here
    } {
        // initialization code here
    }
}

初始化块并不是替代构造器并且他们可以独立于构造器而存在。但是需要提及的最重要的一点就是初始化块会在任何构造器被调用之前被执行。

代码语言:javascript复制
package com.javacodegeeks.advanced.construction;
public class InitializationBlockAndConstructor {
    {
        // initialization code here
    }
    public InitializationBlockAndConstructor() {
    }
}
2.5 构造保障(Construction guarantee)

Java提供了一些开发者所依赖的初始化保障,未初始化的实例和类参数会自动初始化为它们的默认值。

让我们使用下面的例子来确认一下这些默认值。

学 Java 推荐这个实战仓库:https://github.com/javastacks/javastack

代码语言:javascript复制
package com.javacodegeeks.advanced.construction;
public class InitializationWithDefaults {
    private boolean booleanMember;
    private byte byteMember;
    private short shortMember;
    private int intMember;
    private long longMember;
    private char charMember;
    private float floatMember;
    private double doubleMember;
    private Object referenceMember;

    public InitializationWithDefaults() {
        System.out.println( "booleanMember = "   booleanMember );
        System.out.println( "byteMember = "   byteMember );
        System.out.println( "shortMember = "   shortMember );
        System.out.println( "intMember = "   intMember );
        System.out.println( "longMember = "   longMember );
        System.out.println( "charMember = "  
        Character.codePointAt( new char[] { charMember }, 0 ) );
        System.out.println( "floatMember = "   floatMember );
        System.out.println( "doubleMember = "   doubleMember );
        System.out.println( "referenceMember = "   referenceMember );
    }
}

一旦使用new关键字实例化:

代码语言:javascript复制
inal InitializationWithDefaults initializationWithDefaults = new InitializationWithDefaults();

将会在控制台输出如下结果:

代码语言:javascript复制
booleanMember = false
byteMember = 0
shortMember = 0
intMember = 0
longMember = 0
charMember = 0
floatMember = 0.0
doubleMember = 0.0
referenceMember = null
2.6 可见性(Visibility)

构造器受Java可见性规则约束并且可以拥有访问控制修饰符来决定是否其他类可以调用特定的构造函数。

0 人点赞