区分overloading:
每个overloading的方法都必须采用独一无二的自变量类型列表
自变量的顺序也足够我们区分两个方法(尽管我们通常不愿意采用这种方法,因为它会产生难以维护的代码)
// promotion of primitives and overloading // 若我们的数据类型“小于”方法中使用的自变量,就会对那种数据类型进行“转型”处理。 // char 获得的效果稍有些不同,这是由于假期它没有发现一个准确的char 匹配,就会转型为int。 public class PrimitiveOverloading { // boolean can't be automatically converted static void prt(String s){ System.out.println(s); } void f1(char x){prt("f1(char)");} void f1(byte x){prt("f1(byte)");} void f1(short x){prt("f1(short)");} void f1(int x){prt("f1(int)");} void f1(long x){prt("f1(long)");} void f1(float x){prt("f1(float)");} void f1(double x){prt("f1(double)");} void f2(byte x){prt("f2(byte)");} void f2(short x){prt("f2(short)");} void f2(int x){prt("f2(int)");} void f2(long x){prt("f2(long)");} void f2(float x){prt("f2(float)");} void f2(double x){prt("f2(double)");} void f3(short x){prt("f3(short)");} void f3(int x){prt("f3(int)");} void f3(long x){prt("f3(long)");} void f3(float x){prt("f3(float)");} void f3(double x){prt("f3(double)");} void f4(int x){prt("f4(int)");} void f4(long x){prt("f4(long)");} void f4(float x){prt("f4(float)");} void f4(double x){prt("f4(double)");} void f5(long x){prt("f5(long)");} void f5(float x){prt("f5(float)");} void f5(double x){prt("f5(double)");} void f6(float x){prt("f6(float)");} void f6(double x){prt("f6(double)");} void f7(double x){prt("f7(double)");} void testConstVal(){ prt("Testing with 5"); f1(5);f2(5);f3(5);f4(5);f5(5);f6(5);f7(5); } void testChar(){ char x = 'X'; prt("char 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(); } } /* 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) */
我们可能调用一个方法,同时忽略返回值 - 则返回值Overloading就会有问题。- 为它的副作用去调用一个方法。
class Banana { void f(int i) { /* ... */ } } Banana a = new Banana(), b = new Banana(); a.f(1); b.f(2);若只有一个名叫f()的方法,怎样才能知道自己是a还是为b调用的呢?
为了能用简便的、面向对象的语法来书写代码 - 亦即“将消息发给对象”,编译器为我们完成了一些幕后工作。
其中一个秘密就是第一自变量传递给方法f(),而且那个自变量是准备操作的那个对象的句柄。
Banana.f(a,1); Banana.f(b,2);这是内部的表达形式,我们并不能这样书写表达式,并试图让编译器接受它。但是,通过它可理解幕后到底
发生了什么事情。
在构造器里调用构造器
若为一个类写多个构造器,那么经常都需要在一个构造器里面调用另一个构造器,以避免写重复的代码。
可用this关键字做到这一点。
尽管可用this调用一个构造器,但不可调用两个。
构造器调用必须是我们做的第一件事情,否则会收到编译程序的报错信息。
假定我们的对象分配了一个“特殊”内存区域,没有使用new。垃圾收集器只知道释放那些由new分配的内存,所以不知道如何释放对象的“特殊”内存。为解决这个问题,Java 提供了一个名为finalize()的方法,可为我们的类定义它。
在理想情况下,它的工作原理应该是这样的:一旦垃圾收集器准备好释放对象占用的存储空间,它首先调用finalize(),而且只有在下一次垃圾收集过程中,才会真正回收对象的内存。
有时可能发现一个对象的存储空间永远都不会释放,因为自己的程序永远都接近于用光空间的临界点。
因为垃圾收集本身也要消耗一些开销。如永远都不用它,那么永远也不用支出这部分开销。
之所以需要finalize():看起来似乎是由于有时需要采取与Java的普通方法不同的一种方法,通过分配
内存来做一些具有C 风格的事情。
1. 将基本类型设为一个类的数据成员,会初始化;
2. 若定义成相对于一个方法的“局部”变量,编译器会强制程序员初始化该变量,否则报错。
// 不可妨碍自动初始化的进行,它在构建器进入之前就会发生。 class Counter { int i; Counter() { i = 7; } // 那么i 首先会初始化成零,然后变成7。
初始化顺序
// Demonstrates initialization order. // When the constructor is called, to create a Tag object, you'll see a message. 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); // re-initialize t3 } Tag t2 = new Tag(2); // after constructor void f(){ System.out.println("f()"); } Tag t3 = new Tag(3); //at end } public class OrderOfInitialization { public static void main(String[] args) { Card t = new Card(); t.f(); // shows that construction is done } } /* Tag(1) Tag(2) Tag(3) Card() Tag(33) f() */
// Specifying initial values in a class definition 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 { 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); } static Table t2 = new Table(); static Cupboard t3 = new Cupboard(); } /* 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 对象,而且永远都不引用Table.b1 或
Table.b2,那么 static Bowl b1 和b2 永远都不会创建。然而,只有在创建了第一个Table 对象之后(或者
发生了第一次static 访问),它们才会创建。在那以后,static 对象不会重新初始化。
- 初始化的顺序是首先static(如果它们尚未由前一次对象创建过程初始化)
- 接着是非static 对象。
在这里有必要总结一下对象的创建过程。请考虑一个名为 Dog的类:
- 类型为 Dog的一个对象首次创建时,或者Dog 类的static方法/static 字段首次访问时,Java 解释器必须找到Dog.class(在事先设好的类路径里搜索)。
- 找到Dog.class 后(它会创建一个 Class对象,这将在后面学到),它的所有static初始化模块都会运行。因此,static初始化仅发生一次——在Class 对象首次载入的时候。
- 创建一个new Dog()时,Dog 对象的构建进程首先会在内存堆(Heap)里为一个 Dog对象分配足够多的存储空间。
- 这种存储空间会清为零,将Dog中的所有基本类型设为它们的默认值(零用于数字,以及 boolean和char 的等价设定)。
- 进行字段定义时发生的所有初始化都会执行。
- 执行构建器。
多维数组:
// Create multidimensional arrays public class MultiDimArray { static Random rand = new Random(); static int pRand(int mod){ return Math.abs(rand.nextInt()%mod + 1); } public static void main(String[] args) { int[][] a1 = { {1,2,3,}, {4,5,6,}, }; for(int i=0; i<a1.length; i++){ for(int j=0; j<a1[i].length; j++){ System.out.println("a1[" + i + "][" + j + "]= " + a1[i][j]); } } } } /* a1[0][0]= 1 a1[0][1]= 2 a1[0][2]= 3 a1[1][0]= 4 a1[1][1]= 5 a1[1][2]= 6 */
相关推荐
很值得一看的书籍,很多人都推荐,适合有一定java基础的人学习提高
装载的时候,所有static对象和static代码块都会按照本来的顺序初始化(亦即它们在类定义代码里写入的顺序)。保证这个顺序是非常关键的,因为衍生类的初始化可
JAVA思想中文版,CHM格式.
Think-In-Java-Code Thinking In Java 书中源码以及课后练习代码(从第7章开始随着看书的进度一步步更新) 第七章 复用类 7.1 组合语法 7.2 继承语法 7.2.1 初始化基类 7.3 代理 7.4 结合使用组合和继承 7.4.1 确保...
作者:贯穿本书,我试图在您的大脑里建立一个模型——或者说一个“知识结构”。这样可加深对语言的理解。若遇到难解之处,应学会把它填入这个模型的对应地方,然后自行演绎出答案。事实上,学习任何语言时,脑海里有...
Think Data Structures Algorithms and Information Retrieval in Java-OReilly(2017)
Think in java 源码构建编译
think in java 源码整理,应该算是比较全面的,有需要的朋友可以下下来看下
think in java 第四版 源码以及作业 eclipse版本 包含jar包 可以直接导入eclipse
Think in java 的代码源码,里面很详细的习题详解
java think in java (英文第四版)至今为止 被认为是java教程之中权威作品之一
1.11 Java和因特网 1.11.1 什么是Web? 1.11.2 客户端编程 1.11.3 服务器端编程 1.11.4 一个独立的领域:应用程序 1.12 分析和设计 1.12.1 不要迷失 1.12.2 阶段0:拟出一个计划 1.12.3 阶段1:要制作什么?...
Think Data Structures in Java 英文azw3 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除
这个是我花钱买的,现在献给大家......
经典的think in java4,所有源码,帮你早日攻克java学习的堡垒!!!
think-in-effective-teamwork.pptx
这是java编程思想中的练习题,自己感觉不错,上传上去给大家分享~~~~~
这是一本充满智慧的书,与简单的参考书有着截然不同的风格。它现在已成了我进行Java 创作一份主要参考。你的目录做得相当不错,让人一目了然,很快就能找到自己需要的东西。
抽象的进步 1.2 对象的接口 1.3 实现方案的隐藏 1.4 方案的重复使用 1.5 继承:重新使用接口 1.5.1 改善基础类 1.5.2 等价和类似关系 1.6 多形对象的互换使用 1.6.1 动态绑定 ...1.11 Java和因特网