[Java] 初始化与清理
1. 构造器
初始化和清理是涉及安全的两个问题,许多C程序的错误都源于忘记初始化变量,当使用完一个元素时,也很容易忘记清理它。C++引入了构造器的概念,这是一个在创建对象时被自动调用的特殊方法,Java中也采用了构造器,并额外提供了垃圾回收器,对于不再使用的内存资源,垃圾回收器能自动将其释放。
在Java中,通过提供构造器,类的设计者可确保每个对象都会得到初始化。创建对象时,如果类具有构造器,就会自动调用相应的构造器。构造器采用与类相同的名称,也避免名称冲突的问题,例如:
class Test {Test() {System.out.print("Initialize");}
}
public class Constructor {public static void main(String[] args) {new Test();}
}
现在在创建Test的对象时,将会为对象分配存储空间,并调用相应的构造器,这就确保在操作对象前已经被初始化。不接受任何参数的构造器叫默认构造器,它也能带有形式参数, 以便指定如何创建对象,例如:
class Test {Test(int i) {System.out.print("Initialize i");}
}
public class Constructor {public static void main(String[] args) {new Test(10);}
}
有了构造器形式参数,就可以在初始化对象时提供实际参数。构造器是一种特殊类型的方法,它没有返回值(这与void不同),并且别无选择,如果没有定义任何构造器,编译器将会自动创建一个默认构造器。
2. 重载
大多数程序语句要求为每个方法提供一个独一无二的标识符,在Java里,构造器是强制重载方法名的另一个原因。如果需要创建一个类,可以用不同的方法初始化,这就需要多个构造器。由于它们都是构造器,所以必须有相同的名字,即类名。为了让方法名相同而形式参数不同的构造器同时存在,必须用到方法重载,它也可应用于其他方法,例如:
class Test {Test() {system.out.println("Defalut");}Test(int i) {system.out.println("Initialize i");}
}
public class Overloading {public static void main(String[] args) {new Test();new Test(10);}
}
每个重载的方法必须有一个独一无二的参数类型列表,甚至参数顺序的不同,但是使用不同的返回值来区分是不可行的。此外,基本类型能从一个较小的类型自动提升至一个较大的类型,此过程一旦涉及重载,可能会造成一些混淆。
3. this
假如希望在方法的内部获得对当前对象的引用,有专门的关键字:this,它只能在方法内部使用,表示对调用方法的对象的引用,this的用法和其他对象引用相同,但如果在方法内部调用同一个类的另一个方法,就不必使用this,直接调用即可,例如:
class Test {void a() {return this;}void b() {a();}
}
如果为类写了多个构造器,可以使用this在一个构造器中调用另一个构造器。在构造器中,如果为this添加了参数列表,那么将产生对符合此参数列表的某个构造器的明确调用,例如:
class Test {Test(int i) {}Test(String s) {this(10);}
}
尽管可以用this调用一个构造器,但却不能同时调用两个,此外必须将构造器调用置于最起始处,否则编译器会报错。除构造器外,编译器禁止在任何方法中调用构造器。
static方法是没有this的方法,在static方法的内部不能调用非静态方法,这正是static方法的主要用途。
4. 垃圾回收
Java有垃圾回收器负责回收无用对象占据的内存资源。由于垃圾回收器只知道释放经由new分配的内存,所以它不知道如何释放并非使用new获得的特殊内存。
为了应对这种情况,Java允许在类中定义一个名为finalize()的方法,一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用其finalize()方法,并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。这与C++中的析构函数有所不同,当程序员调用delete操作符时,就会调用相应的析构函数,而Java虚拟机如果并未面临内存耗尽的情形,它不会浪费时间去执行垃圾回收以恢复内存,这意味着finalize()并不保证一定会发生。
之所有要有finalize(),是由于在分配内存时可能采用了类似C语言中的做法,而非Java中的通常做法,这种情况主要发生在使用本地方法的情况下。本地方法是一种在Java中调用非Java代码的方式,目前只支持C和C++,在非Java代码中,也许会调用malloc()函数来分配存储空间,所以需要在finalize()中用本地方法调用free()来释放。
5. 初始化
Java尽力保证所有变量在使用前都能得到恰当的初始化。对于方法的局部变量,Java以编译时错误的形式来体现。如果类的数据成员是基本类型,那么它们都保证会有一个初始值,如果定义一个对象引用并且不将其初始化,此引用就会获得一个特殊值null,例如:
class Test {char c;int i;String s;
}
可以通过调用某个方法来提供初始值,也可以带有参数,但这些参数必须是已经被初始化的,例如:
class Test {int i = a(10);int j = a(i);int a(int n) {return n;}
}
静态数据成员的初始化只有在必要时才会进行。如果不创建类的对象,或不引用类的静态数据成员,那么静态数据成员永远都不会被初始化。初始化的顺序是先静态对象,而后是非静态对象。变量定义的先后顺序决定了初始化的顺序,但是不论它们定义在什么位置,都会在任何方法(包括构造器)被调用之前得到初始化。
Java允许将多个静态初始化动作组织成一个特殊的静态子句,它看起来像个方法,但实际只是一段跟在static关键字后面的代码,这段代码仅执行一次,例如:
class Test {static int i;static {i = 10;}
}
6. 数组
数组是相同类型、用一个标识符名称封装到一起的一个对象序列或基本类型数据序列。数组是通过方括号下标操作符"[ ]"来定义和使用的,要定义一个数组,只需在类型名后加上一对空方括号,例如:
int[] a1;
int a2[];
编译器不允许指定数组的大小,定义数组拥有的只是对数组的一个引用,而且没有分配任何存储空间。为了给数组分配存储空间,必须写初始化表达式,例如:
int[] a = {1, 2, 3};
int[] b = new int[]{1, 2, 3};
可以将一个数组赋值给另一个数组,但真正做的只是复制了一个引用,例如:
int[] a1 = {1, 2, 3};
int[] a2;
a2 = a1;
所有数组都有一个固有成员length,可以通过它获知数组内包含了多少个元素,但不能对其修改。Java数组计数也是从第0个元素开始,所以能使用的最大下标数是length-1,与C++不同的是,Java中一旦下标访问过界,就会出现运行时错误,例如:
int[] a = {1, 2, 3};
System.out.print(a.length);
如果在编写程序时,并不能确定数组里需要多少个元素,可以直接用new在数组里创建元素,尽管创建的是基本类型数组,new仍然可以工作,例如:
int[] a;
Random rand = new Random(50);
a = new int[rand.nextInt(20)];
数组元素中的基本数据类型值会自动初始化。
Arrays.toString()方法属于java.util标准类库,它将产生一维数组的可打印版本,例如:
System.out.print(Arrays.toString(new int[]{1, 2, 3}));
7. 枚举类型
在Java SE5中添加了enum关键字,它使我们在需要群组并使用枚举类型集时,可以很方便地处理。在此之前,需要创建一个整型常量集,例如:
public enum Num {ONE, TWO, THREE, FOUR, FIVE
}
由于枚举类型的实例是常量,因此按命名惯例使用大写字母表示。为了使用enum,需要创建一个该类型的引用,并将其赋值给某个实例,例如:
Num n = Num.ONE;
System.out.print(n);
在创建enum时,编译器会自动添加一些有用的特性。尽管enum看起来像是一种新的数据类型,但事实上enum确实是类,并且具有自己的方法。例如,编译器会创建toString()方法,以便显示某个enum实例的名字,还会创建ordinal()方法,用来表示某个特定enum常量的声明顺序,以及static values()方法,用来按照enum常量的声明顺序,产生由这些常量值构成的数组。
转载于:https://blog.51cto.com/hanviseas/1377021
[Java] 初始化与清理相关推荐
- Java 初始化和清理
文章目录 一.constructor 二.overload 三.this 关键字 四.this用于构造器调用 五.清理对象和GC 六.初始化 6.1 成员初始化 6.2 构造器初始化 6.2.1 初始 ...
- java 初始化和清楚_浅谈Java中的初始化和清理
引言 这篇文章我们主要介绍Java初始化和清理的相关内容,这些内容虽然比较基础,但是还是在这边做一个简单的总结,方便以后查阅. 初始化过程 Java尽力保证:所有变量在使用之前都会得到恰当的初始化(对 ...
- java编程思想 初始化_《java编程思想》_第五章_初始化与清理
初始化和清理是涉及安全的两个问题,java中采用了构造器,并额外提供了"垃圾回收器",对于不再使用的内存资源,垃圾回收器能自动将其释放. 一.用构造器确保初始化 java中,通过提 ...
- java 析构函数_《JAVA编程思想》5分钟速成:第5章(初始化和清理)
第五章.初始化和清理 前言 1.初始化顺序(静态成员.非静态成员,构造器.父类构造器)的排序: 2.构造器(constructor)是否可被重写(override)? 3.final, finally ...
- Java编程笔记2:初始化和清理
Java编程笔记2:初始化和清理 图源:Java Switch语句(用法详解)-java教程-PHP中文网 构造器 构造器,在编程领域也会被称作构造函数.事实上我觉得这个名称并不是很恰当,可能相当一部 ...
- java编程思想初始化引用,JAVA编程思想--第5章 初始化与清理
随着计算机革命的发展,"不安全"的编程方式已逐渐成为编程代价高昂的主因之一. 初始化和清理(cleanup)是涉及安全的两个问题.初始化时,忘记初始化时许多错误的来源,还有就是不知 ...
- 一起读Java编程思想(2)---构造器的初始化与清理
初始化与清理 用构造器确保初始化 每个类都要定义一个initialize()方法,提醒在使用对象之前必须调用这个方法,使得类的设计者可以确保每个对象都可以被初始化. 构造函数是没有返回类型的函数,用于 ...
- 读书笔记-内存初始化和清理
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 在Java开发中,对象创建.数据关系.垃圾回收始终是不变的话题,今天我们来简单说一下初始化和清理的问 ...
- 20190816 On Java8 第六章 初始化和清理
第六章 初始化和清理 利用构造器保证初始化 在 Java 中,类的设计者通过构造器保证每个对象的初始化. 构造器名称与类名相同. 在 Java 中,对象的创建与初始化是统一的概念,二者不可分割. 方法 ...
最新文章
- 《机器学习Python实践》——数据导入(CSV)
- 「特征工程」与「表示学习」
- 打印最少硬币的组合-dp+记录路径
- (八)深入浅出TCPIP之TCP长连接与短连接详解
- mysql无法启动如何备份文件_mysql 5.7 停电导致无法启动、如何备份数据,重新安装mysql...
- Rational Rose及RequisitePro安装注意事项
- matlab脑肿瘤识别与分割程序_车牌识别算法
- 会不会导致内存泄漏_使用ThreadLocal不当可能会导致内存泄露
- mc pe linux服务器地址,我的世界手机版服务器地址大全 我的世界PE服务器IP和端口一览...
- 设置FlashBuilder4.7打开时选择项目(显示选择项目对话框)
- 【教程】如何批量图片文字识别软件,批量图片文字识别OCR软件系统,批量图片压缩,PDF批量转文字转图片
- 基于GL Pipeline与光线追踪技术的融合实现的台球模拟器
- 浏览器主页被篡改劫持怎么办、主页被劫持的解决办法
- HTML5期末大作业:基于HTML+CSS+JavaScript仿蘑菇街购物商城设计毕业论文源码
- 《证券投资二十四堂课》读书笔记
- Flask 框架设计模式
- php 热区,jquery如何使热区锚点随图片大小尺寸改变而变化
- 小米手机运行linux,小米6成功刷入UOS国产操作系统,可开机运行
- java第八天,嗯.....自己总结的方法和练习题吧
- 谈谈软件项目合作开发