如何创建和销毁对象

本文是我们名为“ 高级Java ”的学院课程的一部分。

本课程旨在帮助您最有效地使用Java。 它讨论了高级主题,包括对象创建,并发,序列化,反射等。 它将指导您完成Java掌握的过程! 在这里查看 !

目录

1.简介 2.实例构建
2.1。 隐式(生成)构造函数 2.2。 无参数的构造函数 2.3。 带参数的构造函数 2.4。 初始化块 2.5。 施工保证 2.6。 能见度 2.7。 垃圾收集 2.8。 终结者
3.静态初始化 4.施工模式
4.1。 辛格尔顿 4.2。 实用程序/助手类 4.3。 厂 4.4。 依赖注入
5.下载源代码 6.接下来

1.简介

根据TIOBE编程社区索引 ,Java编程语言起源于Sun Microsystems并于1995年发布,是世界上使用最广泛的编程语言之一。 Java是一种通用编程语言。 它对软件开发人员的吸引力主要归功于其强大的库和运行时,简单的语法,丰富的受支持平台集(一次编写,随时随地运行– WORA)和强大的社区。

在本教程中,我们将介绍高级Java概念,并假设我们的读者已经对该语言有所了解。 它绝不是完整的参考,而是将Java技能提升到更高水平的详细指南。

在此过程中,将有很多代码片段需要研究。 在有意义的地方,将使用Java 7语法和Java 8语法来呈现相同的示例。

2.实例构建

Java是面向对象的语言,因此,创建新的类实例(对象)可能是其最重要的概念。 构造函数在新类实例初始化中起着核心作用,而Java提供了一些定义它们的方法。

隐式(生成)构造函数

Java允许定义一个没有任何构造函数的类,但这并不意味着该类将没有任何构造函数。 例如,让我们考虑这个类:

package com.javacodegeeks.advanced.construction;public class NoConstructor {
}

该类没有构造函数,但是Java编译器将隐式生成一个构造函数,并且可以使用new关键字创建新的类实例。

final NoConstructor noConstructorInstance = new NoConstructor();

无参数的构造函数

没有参数的构造函数(或no-arg构造函数)是显式完成Java编译器工作的最简单方法。

package com.javacodegeeks.advanced.construction;public class NoArgConstructor {public NoArgConstructor() {// Constructor body here}
}

使用new关键字创建类的新实例后,将调用此构造函数。

final NoArgConstructor noArgConstructor = new NoArgConstructor();

带参数的构造函数

带参数的构造函数是参数化新类实例创建的最有趣,最有用的方法。 下面的示例定义一个带有两个参数的构造函数。

package com.javacodegeeks.advanced.construction;public class ConstructorWithArguments {public ConstructorWithArguments(final String arg1,final String arg2) {// Constructor body here}
}

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

final ConstructorWithArguments constructorWithArguments = new ConstructorWithArguments( "arg1", "arg2" );

有趣的是,构造函数可以使用特殊的this关键字相互调用。 链式构造函数被认为是一种好习惯,因为它可以减少代码重复并基本上导致具有单个初始化入口点。 例如,让我们添加另一个仅带有一个参数的构造函数。

public ConstructorWithArguments(final String arg1) {this(arg1, null);
}

初始化块

Java还有另一种使用初始化块提供初始化逻辑的方法。 很少使用此功能,但最好知道它的存在。

package com.javacodegeeks.advanced.construction;public class InitializationBlock {{// initialization code here}
}

以某种方式,初始化块可能被视为匿名的无参数构造函数。 特定的类可能具有多个初始化块,并且将按照在代码中定义的顺序全部调用它们。 例如:

package com.javacodegeeks.advanced.construction;public class InitializationBlocks {{// initialization code here}{// initialization code here}}

初始化块不能代替构造函数,可以与它们一起使用。 但是要提到的一点很重要,那就是初始化块总是任何构造函数之前调用。

package com.javacodegeeks.advanced.construction;public class InitializationBlockAndConstructor {{// initialization code here}public InitializationBlockAndConstructor() {}
}

施工保证

Java提供了开发人员可能依赖的某些初始化保证。 未初始化的实例和类(静态)变量将自动初始化为其默认值。

类型 默认值
布尔值
字节 0
0
整型 0
0升
烧焦 \ u0000
浮动 0.0分
0.0天
对象参考 空值

表格1

让我们确认使用以下类作为简单示例:

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关键字实例化后:

final InitializationWithDefaults initializationWithDefaults = new InitializationWithDefaults(),

以下输出将显示在控制台中:

booleanMember = false
byteMember = 0
shortMember = 0
intMember = 0
longMember = 0
charMember = 0
floatMember = 0.0
doubleMember = 0.0
referenceMember = null

能见度

构造函数服从Java可见性规则,并且可以具有访问控制修饰符,该修饰符确定其他类是否可以调用特定的构造函数。

修饰符 子类 其他所有人
上市 无障碍 无障碍 无障碍
受保护的 无障碍 无障碍 无法访问
<无修饰符> 无障碍 无法访问 无法访问
私人的 无法访问 无法访问 无法访问

表2

垃圾收集

Java(尤其是JVM)使用自动垃圾收集。 简而言之,无论何时创建新对象,都会自动为其分配内存。 因此,只要不再引用这些对象,它们就会被销毁并回收其内存。

Java垃圾回收是世代相传的,并且基于以下假设:大多数对象都死于年轻对象(它们在创建后不久就不再被引用,因此可以安全地销毁)。 大多数开发人员过去认为,Java中的对象创建速度很慢,应尽可能避免实例化新对象。 实际上,事实并非如此:用Java创建对象非常便宜且快速。 但是,昂贵的是不必要地创建了长期存在的对象,这些对象最终可能会填满旧的对象并导致世界各地的垃圾回收。

终结者

到目前为止,我们已经讨论了构造函数和对象初始化,但实际上并没有提及任何与之对应的东西:对象破坏。 这是因为Java使用垃圾回收来管理对象的生命周期,垃圾回收器负责破坏不必要的对象并回收内存。

但是,Java中有一个称为终结器的特殊功能,该终结器有点类似于析构函数,但具有执行资源清除的不同目的。 终结器被认为是一个危险的功能(这会导致许多副作用和性能问题)。 通常,它们不是必需的,应该避免使用(非常罕见的情况,大多数情况与本机对象有关)。 终结器的更好替代方案Java 7语言结构引入的,称为try-with-resourcesAutoCloseable接口,该接口允许编写干净的代码,如下所示:

try ( final InputStream in = Files.newInputStream( path ) ) {// code here
}

3.静态初始化

到目前为止,我们已经研究了类实例的构造和初始化。 但是Java还支持称为静态初始值设定项的类级初始化构造。 除了附加的static关键字外,它们与初始化块非常相似。 请注意,每个类加载器仅执行一次静态初始化。 例如:

package com.javacodegeeks.advanced.construction;public class StaticInitializationBlock {static {// static initialization code here}
}

与初始化块类似,您可以在类定义中包括任意数量的静态初始化器块,它们将按照它们在代码中出现的顺序执行。 例如:

package com.javacodegeeks.advanced.construction;public class StaticInitializationBlocks {static {// static initialization code here}static {// static initialization code here}
}

因为可以从多个并行线程触发静态初始化块(第一次执行类加载时),所以Java运行时保证仅以线程安全的方式执行该初始化块。

4.施工模式

多年来,Java社区中出现了一些易于理解且广泛适用的构造(或创建)模式。 我们将介绍其中最著名的:单例,助手,工厂和依赖注入(也称为控制反转)。

辛格尔顿

Singleton是软件开发人员社区中最古老且有争议的模式之一。 基本上,其主要思想是确保在任何给定时间只能创建该类的单个实例。 然而,如此简单,单例引发了很多有关如何使其正确,尤其是线程安全的讨论。 这是朴素的单例类的样子:

package com.javacodegeeks.advanced.construction.patterns;public class NaiveSingleton {private static NaiveSingleton instance;private NaiveSingleton() {        }public static NaiveSingleton getInstance() {if( instance == null ) {instance = new NaiveSingleton();}return instance;}
}

此代码的至少一个问题是,如果由多个线程并发调用,它可能会创建该类的许多实例。 正确设计单例(但以非延迟方式)的一种方法是使用类的static final属性。

final property of the class.
package com.javacodegeeks.advanced.construction.patterns;public class EagerSingleton {private static final EagerSingleton instance = new EagerSingleton();private EagerSingleton() {        }public static EagerSingleton getInstance() {return instance;}
}

如果您不想浪费资源,并且希望在真正需要时懒散地创建单身人士,则需要显式同步,这有可能导致多线程环境中的并发性降低(有关Java并发性的更多详细信息,将在本文中讨论)。本教程的第9部分并发最佳实践 )。

package com.javacodegeeks.advanced.construction.patterns;public class LazySingleton {private static LazySingleton instance;private LazySingleton() {        }public static synchronized LazySingleton getInstance() {if( instance == null ) {instance = new LazySingleton();}return instance;}
}

如今,单例在大多数情况下都不被认为是一个不错的选择,主要是因为单例使代码难以测试。 依赖项注入模式的主导(请参见下面的“ 依赖项注入”部分)也使单身人士不必要。

实用程序/助手类

实用程序或帮助程序类是许多Java开发人员使用的非常流行的模式。 基本上,它代表了非实例化类(与构造函数声明为private ),可选声明为final (有关声明类的更多详细信息final将在本教程的第3部分提供, 如何设计类和接口 ),包含static方法只要。 例如:

package com.javacodegeeks.advanced.construction.patterns;public final class HelperClass {private HelperClass() {        }public static void helperMethod1() {// Method body here}public static void helperMethod2() {// Method body here}
}

从经验丰富的软件开发人员的角度来看,这样的助手通常成为各种不相关方法的容器,这些方法并未找到放置其他位置的方法,但应以某种方式共享并由其他类使用。 在大多数情况下,应避免此类设计决策:始终可以找到另一种方法来重用所需的功能,同时保持代码简洁明了。

事实证明,工厂模式在软件开发人员手中是极其有用的技术。 因此,它具有Java的几种风格,从工厂方法抽象工厂 。 工厂模式的最简单示例是static方法,该方法返回特定类的新实例( factory方法 )。 例如:

package com.javacodegeeks.advanced.construction.patterns;public class Book {private Book( final String title) {}     public static Book newBook( final String title ) { return new Book( title );}
}

有人可能会认为引入newBook 工厂方法没有多大意义,但使用这种模式通常会使代码更具可读性。 工厂模式的另一个变化涉及接口或抽象类( 抽象工厂 )。 例如,让我们定义一个工厂接口

public interface BookFactory {Book newBook();
}

根据库类型,有几种不同的实现:

public class Library implements BookFactory {@Overridepublic Book newBook() {return new PaperBook();}
}public class KindleLibrary implements BookFactory {@Overridepublic Book newBook() {return new KindleBook();}
}

现在, Book的特定类隐藏在BookFactory接口实现的后面,仍然提供了创建书籍的通用方法。

依赖注入

依赖注入(也称为控制反转)被认为是类设计者的一种好习惯:如果某个类实例依赖于其他类实例,则应通过构造函数(或setter,策略)为其提供(注入)那些依赖。等),但不是由实例本身创建的。 让我们考虑以下示例:

package com.javacodegeeks.advanced.construction.patterns;import java.text.DateFormat;
import java.util.Date;public class Dependant {private final DateFormat format = DateFormat.getDateInstance();public String format( final Date date ) {return format.format( date );}
}

Dependant类需要一个DateFormat实例,并且仅在构造时通过调用DateFormat.getDateInstance()创建一个实例。 更好的设计是使用构造函数参数执行相同的操作:

package com.javacodegeeks.advanced.construction.patterns;import java.text.DateFormat;
import java.util.Date;public class Dependant {private final DateFormat format;public Dependant( final DateFormat format ) {this.format = format;}public String format( final Date date ) {return format.format( date );}
}

在这种情况下,该类的所有依赖关系都是从外部提供的,因此更改日期格式和编写测试用例非常容易。

5.下载源代码

  • 您可以在此处下载源代码: com.javacodegeeks.advanced.java

6.接下来

在本教程的这一部分中,我们研究了类和类实例的构造和初始化技术,以及涵盖几种广泛使用的模式的方法。 在下一部分中,我们将剖析Object类及其知名方法的用法: equalshashCodetoStringclone

翻译自: https://www.javacodegeeks.com/2015/09/how-to-create-and-destroy-objects.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/358316.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

msf各种弱口令爆破

msf各种弱口令爆破 Msf: 记录下msf各个爆破弱口令的模块 run post/windows/gather/arp_scanner RHOSTS10.10.10.0/24 使用arp_scanner模块 检测在线主机 metasploit 增加路由 route add 10.10.1.3 255.255.255.0 1使用扫描模块 use scanner/portscan/tcp爆破ssh Msf>us…

[学习笔记]批次需求计划系统-简要

一、该系统的目的二、系统特色(1)来源根据 如上图(2)仅仅补充需求来源的最大值&#xff0c;避免料件多买而造成浪费(3)可透过[发放LRP工单]将生产计划发放成正式工单(4)可透过[发放LRP採购单]将採购计划发放成正式的请购单或者採购单(5)系统会记录计划的来源单据&#xff0c;方…

在浏览器控制台执行以下代码,输入的结果是()

在浏览器控制台执行以下代码,输入的结果是(A) A.4400 4401 4399 4400 B.4400 4401 4401 4402 C.4400 4400 4399 4400 D.4400 4401 4399 4402 E.4400 4401 4401 4400 解析 js在执行之前

iOS-心跳

转载于:https://www.cnblogs.com/zhuyaguang/p/4800703.html

google国内镜像网址收集

搞IT的遇到问题&#xff0c;光靠baidu有时真的解决不了问题&#xff0c;所以时不时的就需要求助google&#x1f602;&#xff0c; 里面有好多国外网友的博客、stackoverflow、github issues、官方文档等等的大量一手英文资料&#xff0c; 但是因为种种原因国家一直不放开Google…

根据 HTML 规范,以下代码中,外层容器 .outer 的宽高分别是:

根据 HTML 规范&#xff0c;以下代码中&#xff0c;外层容器 .outer 的宽高分别是&#xff1a;B <style> .outer { height: 50px; } .inner { width: 120px; height: 100px; } </style><div class"outer"> <span class"inner">co…

分而治之_播放框架模块:分而治之

分而治之通常情况是您开始开发应用程序并继续满足需求。 当您的应用程序变得更大时&#xff0c;您开始意识到将其分为不同组件的便利。 而且&#xff0c;当您开发第二个或第三个应用程序时&#xff0c;您开始认识到可以在不同应用程序之间重用的某些功能。 这是模块化应用程序的…

Mysql身份认证漏洞及利用(CVE-2012-2122)

当连接MariaDB/MySQL时&#xff0c;输入的密码会与期望的正确密码比较&#xff0c;由于不正确的处理&#xff0c;会导致即便是memcmp()返回一个非零值&#xff0c;也会使MySQL认为两个密码是相同的。 也就是说只要知道用户名&#xff0c;不断尝试就能够直接登入SQL数据库。按照…

【剑指offer】十九,数组中出现次数超过一半的数字

题目描述 数组中有一个数字出现的次数超过数组长度的一半&#xff0c;请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次&#xff0c;超过数组长度的一半&#xff0c;因此输出2。分析&#xff1a;找数组中出现次数超过一半的数字&…

从WEB应用的角度,一个应用都需要维护一些不同作用范围的状态, 请问下面哪些状态作用域是WEB应用特有的:( )

从WEB应用的角度&#xff0c;一个应用都需要维护一些不同作用范围的状态&#xff0c; 请问下面哪些状态作用域是WEB应用特有的&#xff1a;( ADF )A.会话 B.全局 C.线程本地 D.请求 E.本地 F.应用 解析 Web程序对象作用域&#xff1a; 常用的有三个&#xff1a;请求…

Java EE 7中的WebSocket客户端API

在本文中&#xff0c;让我们探索谈论较少的Web Socket Client API&#xff0c;以及如何在Java EE 7容器本身中利用它。 Web套接字服务器API规则 JSR 356的服务器端API&#xff08;Java的Web套接字API&#xff09;最常用于构建Web套接字端点实现。 从客户端的角度来看&#xff…

mongo-express 远程代码执行漏洞(CVE-2019-10758)

前言 mongo-express是一款mongodb的第三方Web界面&#xff0c;使用node和express开发。如果攻击者可以成功登录&#xff0c;或者目标服务器没有修改默认的账号密码&#xff08;admin:pass&#xff09;&#xff0c;则可以执行任意node.js代码。 影响版本 mongo-express&#xff…

【转】深入浅出PageRank算法

原文链接 http://segmentfault.com/a/1190000000711128 PageRank算法 PageRank算法是谷歌曾经独步天下的“倚天剑”&#xff0c;该算法由Larry Page和Sergey Brin在斯坦福大学读研时发明的&#xff0c; 论文点击下载: The PageRank Citation Ranking: Bringing Order to the We…

下面的语言中哪些语言是动态语言( )

下面的语言中哪些语言是动态语言(B ) A.C B.JavaScript C.C D.CSS E.Java F.Objective-C 解析 静态语言&#xff08;强类型语言&#xff09; 静态语言是在编译时变量的数据类型即可确定的语言&#xff0c;多数静态类型语言要求在使用变量之前必须声明数据类型。 例…

https://blog.csdn.net/weixin_40412037/article/details/112235003

一、工具简介 说明&#xff1a; 这是一款基于主机的漏洞扫描工具&#xff0c;采用多线程确保可以快速的请求数据&#xff0c;采用线程锁可以在向sqlite数据库中写入数据避免database is locked的错误&#xff0c;采用md5哈希算法确保数据不重复插入。 本工具查找是否有公开e…

前端工程师能力评估测试题(2020最新版附答案及解析)

1.下列哪个样式定义后,内联(非块状)元素可以定义宽度和高度 (C) A.display:inline B.display:none C.display:block D.display:inherit 解析 2.css属性overflow属性定义溢出元素内容区的内容会如何处理。如果值为 scroll,不论是否需要,用户代理都会提供一种滚动机…

埃氏筛法的一般写法(区间筛法)

问题&#xff1a; 求 $[L, R]$ 之间的素数表 解法&#xff1a; 一个合数 $n$ 的最小素因子不超过 $\sqrt{n}$。 先用埃氏筛法求出 $[1,\lfloor \sqrt{R} \rfloor]$ 上的素数表 再在 $[L, R]$ 上用埃氏筛法求素数 const int N(1e5); bool isprime[N]; int prime[N]; void init()…

滥用static_沉思滥用:“强力使用,破坏滥用”

滥用static前英国首相本杰明迪斯雷利&#xff08;Benjamin Disraeli&#xff09;曾用过一句古话&#xff0c;说这是三种谎言&#xff1a;“谎言&#xff0c;该死的谎言和统计数据”。 这里的暗示是&#xff0c;统计数字很容易弥补&#xff0c;因此不可靠。 但是&#xff0c;统计…

Cobalt strike加载插件出现乱码

问题描述 插件 加载成功出现乱码 解决方法 在Cobalt strike目录下执行命令指定编码打开客户端解决。 java -Dfile.encodingutf-8 -XX:ParallelGCThreads4 -XX:AggressiveHeap -XX:UseParallelGC -Xms512M -Xmx1024M -jar cobaltstrike.jar1 成功解决

新网站链接提交入口攻略

很多网站没有被收录,也没有排名,经常有SEO站长向我抱怨。其实提升网站收录有方法和诀窍的。下面我详细的为大家分享,如何向百度提交链接,提升网站被的机率。 很多新手站长,网站上线后没有主动的向搜索引擎提交,spider在短期内无法第一时间发现新网站,这个时候我们 需要…