Java基础第四篇 面向对象的基本概念(中)

                                                               

      Java基础第四篇 面向对象的基本概念(中)

     既然说是面向对象,那么如何产生对象,如何了解对象的生命周期,以及对象在项目中的运用。本篇博客继续探讨面向对象的基本概念,并且尝试更加明了的说明蕴含其中的思想。                                  ---------记  2014.8.10

 

 1.1对象的产生

 

说明:创建对象的根本途径是构造器(构造函数),通过new 关键字来调用某个类的构造器即可创建这个类的实例,这个实例也就是该类的对象。大部分时候,定义一个类,就是为了充分创建该类的实例。同一个类的多个实例具有相同的特征,而类则是定义了多个实例的共同特征,从某个角度讲,类定义的多个实例的特征,因此类不是一种具体的存在,实例才是具体的存在,这些个实例就是对象。

  1.2 创建一个对象包括对象的声明和为对象分配内存空间两个步骤。

1。对象的声明

语法格式:

<类型名> <对象名>;

2。为对象分配内存

语法格式:

<对象名> = new <类型名>();

举例: Person person  = new Person(); //该实例将1,2两个步骤放在一起了

说明:

      1.第一个步骤一般是在某个类的头部定义需要的类的对象。

       第二个步骤一般是在需要的时候再分配内存。或者在类的构造函数中分配内存。分配内存是一个复杂的过程,涵盖了该类的许多方面,不是本博客的重点。

  2.在1.1中已经说到了创建对象是通过关键字new 和 构造函数创建的,因此会有两种情况:

使用new运算符和类的构造方法为声明的对象分配内存,如果类中没有构造方法,系统会调用默认的构造方法(默认的构造方法是无参数的)。

如果类中定义了一个或多个构造方法则系统不再提供默认的构造方法。

 

       那么对象创建完后应该干啥呢,我们可以通过对对象的操作来达到什么样的目的呢?

1.3创建一个类的对象,就意味着这个对象可以使用该类里的所有方法,变量,常量等。因此对象可以通过操作变量来修改自己的状态,通过操作方法,来执行自己的行为。

 Java程序中有一个英文标点符号,可以通过这个标点符号来获取该类的变量和方法

操作如下:

<对象名>.<变量名>

<对象名>.<方法名>

实例:person.age;    //调用Person类的age变量

     person.getName(); //调用person类的获取姓名的方法

这个标点符号相当于调用的动作,可以通过这个标点符号来查看某个类具有哪些属性,方法等(当然是在eclipse等IDE下可以看到,建议初学者先会dos下的操作);

 

2.1对象的使用。工作机制

在上一章中有两个图,演示了方法与方法,变量与变量,方法与变量之间的调用关系,同样对于对象对方法和变量的操作依然有这些关系:

这里说一下对static关键字修饰的方法和变量,对象如何调用 

    当要获取的变量是类变量时,也就是这个变量有static关键字

修饰,可以直接使用类名获取。

语法如下:<类名>.<变量名>

    同理,当要调用的方法是类方法时,也可直接使用类名调用。

语法如下:<类名>.<方法名>

2.2 对象的描述

   总结:类是对象的模版,对象是类的具体表现,每个对象都是类的一个实例,对象与对象之间是互相独立的。

   说明:一个类通过使用new运算符可以创建多个不同的对象,这些对象将被分配不同的内存空间,现在再说得准确些就是:不同的对象的实例变量将被分配不同的内存空间(是属于该对象的而不是属于该类的),如果类中的成员变量有类变量,那么所有对象的同名类变量都分配同一处内存,改变其中一个对象的类变量会同时影响其它对象的同名类变量。所以同一个类的不同对象的类变量(static修饰的变量)是共享的。

 

实例变量和类变量在内存中的分配情况

     当Java程序执行时,类的字节码文件被加载到内存,如果该类没有创建对象,类的实例成员变量不会被分配内存。但是,类中的类变量,在该类被加载到内存时,就分配了相应的内存空间。如果该类创建对象,那么不同对象的实例变量互不相同,即分配不同的内存空间,而类变量不再重新分配内存,所有的对象共享类变量,即所有的对象的类变量是相同的一处内存空间,类变量的内存空间直到程序退出运行,才释放所占有的内存。

 

说明:类变量放在方法区中是这个类的财产(随着类的产生而产生),而实例变量放在堆内存中,被对象使用,每个对象都有自己的一块内存保存所使用的实例变量。

 

说明:还是以person为例: Person  person = new Person();

实际中这行代码产生了两个东西,一个是person变量,另一个是Person对象。

就是说这个person变量是一个引用型(reference)变量,它是一个指针(相当于c,c++中的指针变量),这个指针里存的是该Person对象所在的内存。因为类也是引用型数据类型。

这个person变量放在栈内存中,Person对象则放在堆内存中(这段堆内存可以连续也可以不连续)。

说明:person变量本身只是存储了一个地址值,并未包含任何实际数据。

Person对象拥有一块在堆上的内存空间来存储它的变量,方法,在虚拟机中对堆的数据结构设计中里面一般分为两块,句柄池:存放指针,里面的指针可以指向对象池,也可以指向类数据(这里的类数据放在方法区中)。对象池:存放实例数据。但是可以有个指针用于指向方法区中的类数据,这就可以解释为什么实例方法实例方法可以访问类变量的原因。

这个person引用变量可以通过指向实际的Person对象获取该对象的字段属性(Field域),对象的Field数据实际放在堆内存中,引用变量person只是指向该堆内存里的对象。

 

                                       

这里只是一个简单的模式图,具体的可以参考《深入java虚拟机》

至此一个对象已经产生了。

 

说明:java不允许直接访问堆内存中的对象,只能通过该对象的引用操作该对象,也就说,不管是数组(对数组的声明创建也在堆内存中)还是对象,只能通过引用来访问他们。

堆内存中的对象可以有多个引用,这些引用指向的是同一个对象,因此这些引用对对象的操作都会返回同样的结果。

比如Person  person2 = person;   //将person引用变量赋值给person2,因此person2指向person指向的对象。

我们可以通过这些引用对对象进行操作,比如更改数据,调用方法实现相关功能和业务等。

 

3.1创建对象的方法(扩展)

   创建对象的方式有四种,上面只是描述了最常用的一种。另外三种简述如下:

   第二种方式:使用java的反射机制,调用java.long.Class或者java.long.reflect Constructor 类的newInstance()实例方法。这个方法会返回该类的一个实例对象。

   注意这种方式创建对象实例的时候会调用无参的构造方法,所以必须确保类中有无参的构造函数,否则会抛出java.long.InstantiationException异常。

 第三种方式:调用对象的clone方法,该对象需要重写Object的clone()方法。

     注意该类必须实现java.lang.Cloneable接口,否则会抛出java.lang.CloneNotSupportedException.实现这种方式有两种方法,一是浅拷贝,二是深拷贝,二者是有区别的。

 

第四种方式:使用反序列化手段,该反序列化机制是java中的另一个特点,可以调用java.io.ObjectStream对象的readObject()方法返回该累的实例。

注意:该类必须实现java.io.serializable接口或者 Externalizable接口,否则会抛出IOException。

 

 

4.1对象的销毁

那么对象既然创建完了如果销毁呢,如果无限制的创建对象自然一定会撑爆你的内存,造成内存泄露。

不过java虚拟机的垃圾回收机制可以帮你搞定大部分回收内存的工作,因为java是自动回收内存的,而C,C++,要显示的释放内存。Java虚拟机垃圾回收器(简称GC)会把创建的每一个对象进行标记,会利用隐式的终结方法(finalizer)进行回收。不过垃圾回收器不是定时或者随时进行垃圾回收,通常,当垃圾回收器空闲或者内存不足时,才会进行回收。

说明:java中的每个对象都有一个finalize()方法,protected void  finalize () throwsThrowable{}

垃圾回收器在回收对象时,自动调用对象的finalize()方法来释放系统资源。相当于C++中的free()函数。

 

当堆内存中的java对象没有引用指向它的时候,程序无法再访问该对象,它就像孤狼一样,非常脆弱,也有一定危险,因此java虚拟机会回收该对象,释放该对象所占的内存区。可以把这些引用变量赋值为null,显示的回收对象。数组同样是java的对象,跟类的对象具有相似的地方,在此不做讨论。

 

 

 

 

 

 

   

 

 

    

   

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值