1.静态成员变量
(1)静态成员变量为类变量,所有对象共享同一内存空间。
(2)静态成员变量的声明和定义仅在首次加载类时执行一次。
(3)首次加载类时首先对所有静态成员变量根据类型默认赋初值,然后再对有右值的附右值。
2.静态初始化块
(1)静态初始化块仅在首次加载类时执行一次。
(2)多个静态成员变量与静态初始化块参照出现顺序先后执行。
3.成员变量
成员变量定义在每次实例化对象时在构造函数之前执行。
4.初始化块
(1)初始化块在每次实例化对象时在构造函数之前执行。
(2)多个成员变量与初始化块参照出现顺序先后执行。
总的来说,在不涉及继承的前提下,当首次加载类时,按照如下顺序执行。
(1)按照出现的顺序先后执行静态成员变量定义与静态初始化块。
(2)按照出现顺序先后执行成员变量定义与初始化块。
(3)执行构造函数。
(4)再次实例化对象时只执行第(1)、第(2)步即可。
在使用for控制语句的过程中,还有一些其他注意事项:
1、 当for循环语句中的所有表达式都省略时,它是一个没有结束条件的无限循环。
2、 for循环中也可以只有部分表达式。
3、 步长可以递增或者递减,它只是一个循环执行之后的语句,通常用于步长,但是根据它的特点也可以用于其他用途。
4、 for循环表达式中可以使用逗号操作符。
break和continue之间的区别如下:
1、 break会中断当前循环。
2、 continue会忽略它之后的本次循环代码。
3、 break结合标签使用时,会中断它们之间的循环,不再继续执行。
4、 continue结合标签使用时,会忽略它们之间的本次循环,继续下一次的循环。
数组有几个关键点要注意:
1、 数组是相同数据类型的集合。
2、 数组是一个对象,只能使用new进行实例化。
3、 数组要有一个变量对象引用,否则无法使用,这个变量是指向了数组对象的首地址。通过这个变量可以操作数组。
4、 数组使用“[ ]”表示,将一个类型后面加上这个符号就表示一个数组类型。
5、 数组的大小是固定的,一旦定义并实例化完成后,容量大小是不可以变化的,所以实例化后一定要能够明确数组的大小,否则定义不成功。
6、 数组中的对象称作元素。定义数组并初始化时,使用“{ }”大括号初始化数组的元素。
7、 数组元素存储空间是连续的,每一个元素都有一个唯一的索引。
8、 数组的索引从0开始,最大索引是数组容量数减1,即oneArray.length-1。超出索引访问会抛出运行时异常。Java运行 期检测客户是否超范围访问数组元素的机制是保证安全访问数组的有力保障。
9、 多维数组的定义和一维数组是一样的。一维数组可以认为是一列数据的集合,二维数组可以认为是一个平面的表格,有行和列之分,三维数组可以认为是一个立方体样式的集合,有行、列和深度。多维数组定义后,大小也是要确定的。
程序运行时,对象如何分配的呢?有以下5个地方可以存储数据。
1、 寄存器:这是最快的存储区,它位于处理器内部。数量极其有限,Java中不能直接控制寄存器的存储。
2、 堆栈:位于通用RAM中,它的处理速度仅次于寄存器,它通过指针的移动快速分配和释放存储。创建程序时,Java系统必须知道存储在堆栈内所有项的确切生命周期,便于分配和释放存储,对象的引用存储在堆栈中,light变量就存储在堆栈中,但是Light对象并不存储在这里。
3、 堆:一种通用的内存池(也位于RAM中),用于存放Java类对象。堆的好处是编译器不需要知道数据的生命周期,在堆中随时根据需要都可以创建对象,但是对象的存储分配和清理要比堆栈复杂得多。Light对象被存储在堆中。
4、 常量存储:常量值通常直接存储在程序代码内部。
5、 非RAM存储:数据被存储在程序之外,通过流对象或者持久化对象实现。流对象将对象转化成字节流发送到另一个程序或者机器。持久化存储是对象被永久地存储在磁盘上,下次程序运行时,可以直接转化为当时存储时状态得对象。
对象得销毁与回收:
1、 Java的垃圾回收器是后台自动执行的。
2、 只在判断内存不够时,才会执行。
3、 使用System.gc( )可以强调执行一次(并不保证一定会执行)垃圾回收工作。但是回收的结果无法控制。
4、 使用finalize处理非new方式分配的空间释放问题,不要用它来处理其他情况。
5、 无需关心new方式创建的对象释放问题。
Java中常用的保存数据状态的类称为JavaBean,它是一套基本规范:
1、 JavaBean类必须是一个个公共类,并将其访问属性设置为public。
2、 JavaBean类必须有一个空的构造函数:类中必须有一个不带参数的公共默认构造函数,此构造函数也应该通过调用各个属性的设置方法来设置属性的缺省值。
3、 一个JavaBean类不应该有公共成员变量,类变量都为private。
4、 持有成员变量值只能通过一组存取方法(getXxx和setXxx)来访问:对于每个属性,应该有一个带匹配公用getter和setter方法的专用成员变量。
方法的定义很简单:
1、 方法要有一个有意义的方法名称。
2、 方法要有一个返回值(例如int),如果没有返回值,使用void表示。
3、 方法具有一定的参数列表(例如int ampere)。
4、 方法可使用权限修饰符进行修饰(例如public)。
5、 方法也可以使用final、static等进行修饰来表达不同的用途。
6、 方法的实现体。使用大括号表示实现体的边界。
方法的签名:
1、 方法名称;
2、 参数类型列表。
Java提供了三种关键字:private、protected、public。
1、 private:表示只能类本身的成员可以使用。
2、 protected:表示类、本类、以及继承于本类的子类可以访问。
3、 public:表示所有人都可以访问。
4、 还有一种没有关键字的修饰,表示包访问权限(package)。
可见性由大到小:public、protected、package(包访问权限)、private。
静态函数的特点就是不依赖类的实例存在,可以直接通过类名调用。
私有的构造函数保留了创建对象的权力,这种权力的保留,可以带来益处:
1、 可以保留实例化Light及Light子类的权利。
2、 可以保留是否每次调用都创新Light对象的权力。
多态性:
多态的定义:在运行时刻接口匹配的对象能互相替换的能力,指的是运行时多态。
这里重点是:
1、 替换行为发生在运行时刻。
2、 运行时刻要有能力判断对象接口是否匹配。
3、 替换后,调用替换对象的方法。
实现多态的基本步骤:
1、 需要继承。
2、 子类重写父类方法。
3、 接口设计针对父类编程。
4、 客户创建具体的子类传递给接口。
从多态的实现代码中可以知道:
1、 只有继承,子类才有机会重写父类同样的方法,才能体现对象被替换后,相同接口表现不同的行为。
2、 子类可以直接重用父类方法,但是那样体现不出执行时行为所体现的不同结果,只有重写了父类的方法,运行时才能体现不同的行为。
3、 多态的关键点是父子关系中相同行为的不同表现,相同行为体现在函数的签名一致,即客户看到的对象服务接口完全一致。
4、 另一方面是编写代码时,针对父类编程,只有这样才能够利用向上转型,将所有的子类对象一般化对待,代码才具有一般性,才能达到同样的代码表现出不同的行为特点。
构造函数是不能被继承的,只能在子类初始化时调用,所以不存在重写问题,构造函数只能在一个类中被重载。
一个抽象类中,至少有一个以上的抽象函数,其中可以混合定义具体的函数。
一个类中如果没有任何抽象元素,它也可以被定义为一个抽象类型。这表示设计者不希望用户直接实例化它,只希望通过子类来实现具体的应用。
抽象类(Abstract Class)较普通的具体类(Concrete Class)实际上并无太大区别,只是它是一个具有抽象方法的不能直接实例化的类,其他和普通类型没有区别。
所以:
1、 抽象类可以有构造方法。
2、 抽象类中可以有普通成员变量。
3、 抽象类中可以包含非抽象的普通方法。
4、 抽象类中的抽象方法的访问类型可以是public、protected和默认类型。
5、 抽象类中可以包含静态方法。
6、 抽象类中可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意。
7、 抽象类只能继承一个类。
完全实现了所有接口方法的的类就是一个具体的类。
部分实现了接口方法的类是一个抽象的类。
接口通过实现(implements)演变成为一个类(class)。
接口可以通过继承(extends)创建新的子接口。
可以把接口理解为一个完全抽象的类,只是它的用法稍有区别。
1、 它使用关键字implements实现到类的演变。
2、 可以多重实现(类似多重继承,但是更纯净!)。
3、 方法默认全部公有public。
4、 所有方法只有定义,没有实现。
5、 所有变量默认都是公有静态final的常量,而且必须被显式始化。
接口和抽象类有很多相似之处,但是:
1、 接口中不能有构造方法。
2、 接口中没有普通成员变量,只有常量。
3、 接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
4、 接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
5、 接口中不能包含静态方法。
6、 抽象类和接口中都可以包含静态成员变量。但接口中定义的变量只能是public static final 类型,并且默认即为public staticfinal 类型。
7、 一个类可以实现多个接口,但只能继承一个类。