第四章读后感
来源:互联网 发布:心内事无人知的图片 编辑:程序博客网 时间:2024/05/23 19:14
在Java中,“初始化”和“创建”被捆绑在一起,两者不能分离。
构造器是一种特殊类型的方法,因为它没有返回值,不会返回任何东西。New表达式确实返回了对新建对象的引用,但构造器本身并没有任何返回值。
类可以有两个以上的构造器,一个不带形式参数,另外的带有参数。
每个重载的方法都必须有一个独一无二的参数类型列表。
涉及基本类型的重载
基本类型能从一个“较小”的类型自动提升至一个“较大”的类型。如:
public class PrimitiveOverloading {
void f1(char x) { System.out.println("f1(char)"); }
void f1(byte x) { System.out.println("f1(byte)"); }
void f1(short x) { System.out.println("f1(short)"); }
void f1(int x) { System.out.println("f1(int)"); }
void f1(long x) { System.out.println("f1(long)"); }
void f1(float x) { System.out.println("f1(float)"); }
void f1(double x) { System.out.println("f1(double)"); }
void f2(byte x) { System.out.println("f2(byte)"); }
void f2(short x) { System.out.println("f2(short)"); }
void f2(int x) { System.out.println("f2(int)"); }
void f2(long x) { System.out.println("f2(long)"); }
void f2(float x) { System.out.println("f2(float)"); }
void f2(double x) { System.out.println("f2(double)"); }
void f3(short x) { System.out.println("f3(short)"); }
void f3(int x) { System.out.println("f3(int)"); }
void f3(long x) { System.out.println("f3(long)"); }
void f3(float x) { System.out.println("f3(float)"); }
void f3(double x) { System.out.println("f3(double)"); }
void f4(int x) { System.out.println("f4(int)"); }
void f4(long x) { System.out.println("f4(long)"); }
void f4(float x) { System.out.println("f4(float)"); }
void f4(double x) { System.out.println("f4(double)"); }
void f5(long x) { System.out.println("f5(long)"); }
void f5(float x) { System.out.println("f5(float)"); }
void f5(double x) { System.out.println("f5(double)"); }
void f6(float x) { System.out.println("f6(float)"); }
void f6(double x) { System.out.println("f6(double)"); }
void f7(double x) { System.out.println("f7(double)"); }
void testConstVal() {
System.out.println("Testing with 5");
f1(5);f2(5);f3(5);f4(5);f5(5);f6(5);f7(5);
}
void testChar() {
char x = 'x';
System.out.println("char argument:");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
}
void testByte() {
byte x = 0;
System.out.println("byte argument:");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
}
void testShort() {
short x = 0;
System.out.println("short argument:");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
}
void testInt() {
int x = 0;
System.out.println("int argument:");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
}
void testLong() {
long x = 0;
System.out.println("long argument:");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
}
void testFloat() {
float x = 0;
System.out.println("float argument:");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
}
void testDouble() {
double x = 0;
System.out.println("double argument:");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
}
public static void main(String[] args) {
PrimitiveOverloading p =
new PrimitiveOverloading();
p.testConstVal();
p.testChar();
p.testByte();
p.testShort();
p.testInt();
p.testLong();
p.testFloat();
p.testDouble();
}
} ///:~
输出结果
Testing with 5
f1(int)
f2(int)
f3(int)
f4(int)
f5(long)
f6(float)
f7(double)
char argument:
f1(char)
f2(int)
f3(int)
f4(int)
f5(long)
f6(float)
f7(double)
byte argument:
f1(byte)
f2(byte)
f3(short)
f4(int)
f5(long)
f6(float)
f7(double)
short argument:
f1(short)
f2(short)
f3(short)
f4(int)
f5(long)
f6(float)
f7(double)
int argument:
f1(int)
f2(int)
f3(int)
f4(int)
f5(long)
f6(float)
f7(double)
long argument:
f1(long)
f2(long)
f3(long)
f4(long)
f5(long)
f6(float)
f7(double)
float argument:
f1(float)
f2(float)
f3(float)
f4(float)
f5(float)
f6(float)
f7(double)
double argument:
f1(double)
f2(double)
f3(double)
f4(double)
f5(double)
f6(double)
f7(double)
Press any key to continue...
如果传入的数据类型小于方法中声明的形式参数类型,实际数据类型就会被提升。Char类型略有不同,会被提升至int类型。
如果传入的实际参数类型大于重载方法声明的形式参数,就得在括号里面写上类型名称,做必要的类型转换,如下:
public class Demotion {
static Test monitor = new Test();
void f1(char x) { System.out.println("f1(char)"); }
void f1(byte x) { System.out.println("f1(byte)"); }
void f1(short x) { System.out.println("f1(short)"); }
void f1(int x) { System.out.println("f1(int)"); }
void f1(long x) { System.out.println("f1(long)"); }
void f1(float x) { System.out.println("f1(float)"); }
void f1(double x) { System.out.println("f1(double)"); }
void f2(char x) { System.out.println("f2(char)"); }
void f2(byte x) { System.out.println("f2(byte)"); }
void f2(short x) { System.out.println("f2(short)"); }
void f2(int x) { System.out.println("f2(int)"); }
void f2(long x) { System.out.println("f2(long)"); }
void f2(float x) { System.out.println("f2(float)"); }
void f3(char x) { System.out.println("f3(char)"); }
void f3(byte x) { System.out.println("f3(byte)"); }
void f3(short x) { System.out.println("f3(short)"); }
void f3(int x) { System.out.println("f3(int)"); }
void f3(long x) { System.out.println("f3(long)"); }
void f4(char x) { System.out.println("f4(char)"); }
void f4(byte x) { System.out.println("f4(byte)"); }
void f4(short x) { System.out.println("f4(short)"); }
void f4(int x) { System.out.println("f4(int)"); }
void f5(char x) { System.out.println("f5(char)"); }
void f5(byte x) { System.out.println("f5(byte)"); }
void f5(short x) { System.out.println("f5(short)"); }
void f6(char x) { System.out.println("f6(char)"); }
void f6(byte x) { System.out.println("f6(byte)"); }
void f7(char x) { System.out.println("f7(char)"); }
void testDouble() {
double x = 0;
System.out.println("double argument:");
f1(x);f2((float)x);f3((long)x);f4((int)x);
f5((short)x);f6((byte)x);f7((char)x);
}
public static void main(String[] args) {
Demotion p = new Demotion();
p.testDouble();
monitor.expect(new String[] {
"double argument:",
"f1(double)",
"f2(float)",
"f3(long)",
"f4(int)",
"f5(short)",
"f6(byte)",
"f7(char)"
});
}
}
如果没有定义构造器,编译器回帮你自动创建一个缺省构造器。但是,如果已经定义了一个构造器(无论有无参数),编译器就不会帮你自动创建缺省构造器,如:
class Hat{
Hat (int i){}
Hat(double d){}
}
现在,如果你这样写: new Hat(); 就会报错。
对象可能不被垃圾回收;垃圾回收并不等于“析构”;垃圾回收只与内存有关。无论垃圾回收还是终结,都不保证一定会发生,如果Java虚拟机并未面临内存耗尽的情形,它是不会浪费时间去执行垃圾回收以恢复内存的。
Finalize()方法会在垃圾回收器清除对象之前被调用,但不要依赖它回收任何短缺资源,因为不确定该方法何时被调用。
之所以要有finalize()方法,是由于在分配内存时可能采用了类似c语言中的做法,这种情况主要发生在使用“本地方法”的情况下。本地方法是在Java中调用非Java代码的方式(目前只支持c/c++)。
书中对垃圾回收器如何工作进行了详细的讲解,可以好好看看。
类的每个基本类型数据成员保证都会有一个初始值,如果没有指定,会赋给默认值;单对于定义于方法内部的局部变量,必须指定初始值,否则会报错。
对于非基本类型的对象,在初始化之前不能使用,否则会报错。
Class CInit{
Int j = g(i);
Int I = f();} 这样写就不对了,该程序的正确性取决于初始化的顺序。
对于所以基本类型和对象引用,包括在定义时已经指定初始值的变量,无法组织自动初始化的进行,它将在构造器被调用之前发生。
在类的内部,变量定义的先后顺序决定了初始化的顺序。即使变量定义散布于方法定义之间,它们仍旧会在任何方法(包括构造器)被调用之前得到初始化。如:
class Tag {
Tag(int marker) {
System.out.println("Tag(" + marker + ")");
}
}
class Card {
Tag t1 = new Tag(1); // Before constructor
Card() {
// Indicate we're in the constructor:
System.out.println("Card()");
t3 = new Tag(33); // Reinitialize t3
}
Tag t2 = new Tag(2); // After constructor
void f() {
System.out.println("f()");
}
Tag t3 = new Tag(3); // At end
}
public class OrderOfInitialization {
static Test monitor = new Test();
public static void main(String[] args) {
Card t = new Card();
t.f(); // Shows that construction is done
monitor.expect(new String[] {
"Tag(1)",
"Tag(2)",
"Tag(3)",
"Card()",
"Tag(33)",
"f()"
});
}
} ///:~ t3被初始化两次,一次在调用构造器之前,一次在调用期间。
对于静态数据的初始化,就有点复杂了:
import com.bruceeckel.simpletest.*;
class Bowl {
Bowl(int marker) {
System.out.println("Bowl(" + marker + ")");
}
void f(int marker) {
System.out.println("f(" + marker + ")");
}
}
class Table {
static Bowl b1 = new Bowl(1);
Table() {
System.out.println("Table()");
//b2.f(1);
}
void f2(int marker) {
System.out.println("f2(" + marker + ")");
}
static Bowl b2 = new Bowl(2);
}
class Cupboard {
Bowl b3 = new Bowl(3);
static Bowl b4 = new Bowl(4);
Cupboard() {
System.out.println("Cupboard()");
b4.f(2);
}
void f3(int marker) {
System.out.println("f3(" + marker + ")");
}
static Bowl b5 = new Bowl(5);
}
public class StaticInitialization {
static Test monitor = new Test();
public static void main(String[] args) {
System.out.println("Creating new Cupboard() in main");
new Cupboard();
System.out.println("Creating new Cupboard() in main");
new Cupboard();
t2.f2(1);
t3.f3(1);
monitor.expect(new String[] {
"Bowl(1)",
"Bowl(2)",
"Table()",
"f(1)",
"Bowl(4)",
"Bowl(5)",
"Bowl(3)",
"Cupboard()",
"f(2)",
"Creating new Cupboard() in main",
"Bowl(3)",
"Cupboard()",
"f(2)",
"Creating new Cupboard() in main",
"Bowl(3)",
"Cupboard()",
"f(2)",
"f2(1)",
"f3(1)"
});
}
static Table t2 = new Table();
static Cupboard t3 = new Cupboard();
} ///:~
这里面需要注意的是:
1. 如果不创建Table对象,则Table{……}中的语句不会执行,同理cupboard
2. 初始化的顺序是先“静态”对象,后“非静态” 对象
3. 静态对象的初始化只执行一次:当首次生成这个类的一个对象时,或者首次访问属于那个类的静态数据成员时
数组的初始化
import com.bruceeckel.simpletest.*;
public class Arrays {
static Test monitor = new Test();
public static void main(String[] args) {
int[] a1 = { 1, 2, 3, 4, 5 };
int[] a2;
a2 = a1; //a2和a1指向同一个地址
for(int i = 0; i < a2.length; i++)
a2[i]++; //可以改变数组元素状态
for(int i = 0; i < a1.length; i++)
System.out.println(
"a1[" + i + "] = " + a1[i]);
monitor.expect(new String[] {
"a1[0] = 2",
"a1[1] = 3",
"a1[2] = 4",
"a1[3] = 5",
"a1[4] = 6"
});
}} ///:~
- 第四章读后感
- C++ Primier读后感 之 第四章 表达式
- java2实用教程第四-五章读后感
- 章节读后感-第一部分-第四章:函数和递归
- Spring实战第四版读后感
- (读后感)C++ Primer(第四版) 第二章 变量和基本类型
- (读后感)C++ Primer(第四版) 第三章 快速入门 标准库类型
- 《一本书读懂TCP/IP》读后感——第四章TCP/IP网络机构
- (读后感)C++ Primer(第四版) 第一章 快速入门
- 第二章读后感
- 第三章读后感
- 第七章读后感
- 读后感
- 读后感
- 读后感
- >读后感
- 读后感
- 读后感
- 利用PowerDesigner批量生成测试数据
- Visual c++ 技术内幕 Ex21a,例子可耻di失败鸟.
- 技巧CE
- 重新计算自动编号
- 常用函数
- 第四章读后感
- java中两个字符串“Equals”和“==”的区别
- 持久层框架:ibatis学习心得,欢迎大家交流:wyf_cjl@sohu.com
- 用Eclipse统一开发环境
- javascript--拿你沒轍9/23
- :)活活。。Blog开通
- 成为一个受欢迎的人(转自开复学生网)
- helix server 架设多服务图文教程
- 如何获得行之有效的学习方法