1.创建类的对象
一、创建对象的两种方式(不仅仅只有两种)
1.使用构造函数
2.使用返回对象的静态函数
- 有函数名,可读性更强,参数相同时构造函数,不容易进行重载
- 不必在每次都创建一个新的对象 eg:Boolean.valueOf(boolean b);//不会创建新的对象,只会返回TRUE、FALSE(Boolean对象实例,创建一次反复使用)
二、Java中创建类的对象
1.方法中的局部变量-----必须初始化才可以进行使用
2.类的属性变量---------可以不进行初始化
对象的reference初始化为null
基本类型变量会自动的初始化
3.变量的初始化顺序
3.1首先初始化类的属性-----调用他们的构造函数
3.2调用自己的构造函数
例子:
class House{ /** * class House * 模拟一个房间 */ Window w1=new Window(1); Window w2=new Window(2); Window w3=new Window(3); House(){ /** * construct function */ print("House"); w3=new Window(33);//在构造函数中再次初始w3 } void f(){ print("f()"); } } public class OrderOfInitialization { /** *class OrderOfInitialization * 为了演示类中属性的初始化顺序 */ public static void main(String[] args){ new House().f(); } }
运行结果:
1.创建 Window(1);Window(2);Window(3); 2.调用House的构造函数 3.调用f()
准确的创建过程是这样的:
1.main函数中,创建了一个House的对象,首先会创建并初始化House类的实例的属性,也就是w1,w2,w3(如果有父类的话先调用父类的构造函数)
2.之后开始调用House类的构造函数,其中首先重新初始化了w3之后调用了House的成员函数f();
3.这里要注意的是:每创建一个House实例,这个House的属性,w1,w2,w3都会被自动的初始化一次。
static属性除外,它只会创建一次,而且是在最开始的时候,也就是类创建的时候与对象的创建无光(但是只有在用到的时候(用到类)才会创建static对象)
4.类的属性的初始化
4.1 静态成员属性
这段代码只会在类第一次被使用的时候被调用
static{
#进行初始化
}
4.2 非静态的成员属性
每创建一个对象,该段代码都会被执行一次
{
#进行初始化
}
三、JAVA中的对象的清理工作----仅仅是简单介绍
Java和C++中间有一堵由动态内存分配和垃圾回收技术组成的高墙,Java没有析构函数,程序员不能决定对象什么时候会被内存回收。
3.1如何判断对象是不是"无用"
Java虚拟机会对对象进行"可达性分析"(并不是有的文章写的使用引用计数器进行判断),判断对象是不是没用了,对于不可达的对象,虚拟机会把对象驾到队列中(F-Queue)进行第一次标记,如果这些对象的finalize()函数被执行过,或者不存在,那么就不进行处理,否则会对对象在此进行标记,在下一次垃圾回收的时候进行内存的回收,如果期间对象重新被引用了,那么就不进行垃圾回收,这个过程就是垃圾回收的二次标记
总结:
1.使用可达性分析判断对象的状态,使用二次标记调用finalize()函数
2.finalize() 函数并不是析构函数(C++销毁对象的空间时候必须调用析构函数,如果程序没有错误,对象一定会被销毁),Java中的对象是不一定会销毁:1. 对象可能不会被垃圾回收 2.垃圾回收函数finalize() 并不是析构函数
3.Java虚拟中中的垃圾回收算法与虚拟机相关,新生代基于复制复制法,老年代基于标记整理------具体不生入
四、Java基础中我觉得比较重要的知识点
4.1java 单根继承
类--java中的所有类都有相同的基类(object)
这使得java中的所有类都有一些相同的function:比如equals、hashcode、wait、notify、notifyAll等
java是多实现的,可以实现多个接口
4.2 引用操作对象
String s=new String(“java String"); #s是String类的一个对象的引用
String s; #引用而不创建对象—不是好习惯,和基本类型一样,如果s是函数的局部变量,那么s必须初始化,如果s是类的属性,那么会自动的初始化为null
4.3 可以理解为java函数都是传值么?
对于基本数据类型------下边的函数其实是不起作用的,说明是传值
public void swap(int a,int b){ int tmp = a; a = b; b = tmp; }
对于类的实例,包括数组
public static void tricky(Point arg1, Point arg2) { arg1.x = 100; arg1.y = 100; Point temp = arg1; arg1 = arg2;//这步是不起作用的(不准确) arg2 = temp; }
说明
这里传递的是值,传递的值是对象引用的副本,调用函数之后么,传入函数的对象都有两个引用,具体的说明可以看参考文献的文章写的很清楚。
由于传递的是值的引用的副本,所以赋值是有效的
参考文献:
1.http://www.importnew.com/3559.html
问题-怎么对值进行交换?
法一
int a = 4; int b = 5; public void swap(){ int tmp = a; a = b; b = tmp; }
法二:利用数组
public<T> void swap(T[] arrays){ T temp=arrays[0]; arrays[0]=array[1]; array[1]=temp; }
4.4一些细碎的知识点----有点乱
java中内存管理
存储器--速度最快,java中不能直接操作寄存器,也不能直接申请寄存器的存储空间,都是自动完成的
stack--对象引用、局部变量表、returnAddress
heap--对象(new 出来的东西都存储在堆中)
常量--编译期间会把常量存入常量池,常量池在java中属于方法区(常量池)
java基本类型
基本类型的存储空间并不像其他的语言那样随着平台,机器的改变而改变,java的的跨平台特性。--------字节码
基本类型的创建于C++相同,不使用new的方式,存储在stack中。
boolean大小
boolean a=true;//这个a在JVM中占4个字节即:32位。
boolean[] b = new boolean[10];//数组时,每一个boolean在JVM中占一个字节。
java中的数组
自动的初始化,null
java中的作用域与对象销毁
{/*变量的作用域(同一个函数中不能有相同名称的变量)*/ int x=10; { int x=20; } }
上述的代码在java中不能编译通过,会提示变量已经被定义过(挺好的本来就没有必要,虽然在C++等很多的程序设计语言之中时可以这么写的)
{
String s=new String(“s String ");
}/*out of scope,此时s,引用对象(stack)已经被销毁,而String对象还继续存在*/
程序员不用关注对象所占的内存空间的释放问题,java的垃圾回收器运行在后台,用来监控new出来的所有对象,一旦不再需要的时候就自动的释放它所占的内存空间。
static 关键字(属性)
一般情况下类描述的都是类对象的属性或者方法,必须new 出类的实例才可以调用属性或者调用这些方法。
有两种特殊的情况
1.不创建对象,也希望可以调用这些function,使用这些属性
2.一个类的多个对象希望能够共享的属性,就用static关键字来限制 eg:static int x=10;
无论创建多少个类的实例,其中的x都只创建一次,可以使用它来进行各个对象之间的通信。
static 属性可以直接使用类名称直接调用(也可以使用对象引用来调用),非static对象则不行,必须使用对象的引用来访问类的属性。
static function(方法)
main方法必须是static的原因就是:main是应用程序的入口(操作系用调用),原因就是没有创建类的实例的情况下就调用了main函数,所以main函数必须是static函数。
不能使用非static对象和static函数