Java入门:创建多个对象
当使用一个类实例化多个对象时,多个对象之间是什么关系?他们各自的数据会不会发生混淆?这次课跟大家讲解一下这个问题。学完本次课,大家应该对对象在内存中的表示方式有一个初步的了解,为理解更深入的面向对象概念打一个基础。
编程任务:小明家的狗狗
我们还是通过一个程序任务来理解相关概念。先看看任务描述:小明养了两只小狗,一只叫旺财,白色,3岁;另一只叫小强,黄色,2岁。我们通过键盘向小狗发出指令,当我们输入旺财的时候,旺财需要做自我介绍。当我们输入小强的时候,小强要做自我介绍。当我们输入的既不是旺财,又不是小强的时候,输出“木有这只小狗”。我们用面向对象的方法来完成这个任务。
创建类和对象
使用面向对象的方法编写程序,通常包含如下三个核心步骤:
1.创建与待解决问题相关的类
2.定义属于某类的对象
3.使用new关键字实例化该对象
从编程任务的描述我们可以看到。两只小狗的共同状态特征是姓名和年龄,行为特征是"自我介绍",因此,可以声明一个Dog类如下:
第一步:新建一个项目:DemoDogs
第二步:在项目中新增一个类:AppMain,项目的入口主函数main放在该类中。


新建AppMain类
AppMain类代码如下:

第三步:在项目中新增一个类:Dog,类代码如下:
public class Dog {
int age;
String name;
public void Introduce(){
System.out.println("我是"+name+",我今年"+age+"岁了");
}
}
第四步:修改AppMain类的main函数:
public class AppMain {
public static void main(String[] args) {
// TODO Auto-generated method stub
Dog dog1 = new Dog();
Dog dog2 = new Dog();
}
}
对象实例化的过程解释
我们来看一下定义并实例化一个对象的具体过程。Dog dog1 = new Dog();这样一条语句,可以分成3个步骤来理解。在具体讲解之前,我们先要弄清一个事实:在运行程序的时候,数据是放在内存中的。

首先,Dog dog1部分,会在计算机栈内存中分配一块空间,这块空间的名称是dog1,并且dog1的值只能是一个内存地址,该地址里存放的必须是一个Dog对象。
其次,new Dog()部分,会在堆内存里面分配一块区域(在右边图中用两个橙色方格来表示,白色部分表示的是内存其它区域),假设刚分配到的这块内存区域的地址是0x1000(至于真实地址是什么,我们就没必要知道了,cpu自己知道就行了)。这块内存区域用来存放Dog对象的成员变量,即一个name成员变量和一个age成员变量。
最后,第三个步骤是赋值操作,赋值操作就是将刚才new出来的Dog对象所在的内存空间地址0x1000赋值给变量dog1。
请注意:这里将dog1称为变量,只是为了表述方便。其实dog1所代表的是内存中一个Dog对象,所以以后我们直接称dog1为对象dog1,或者实例dog1,不再称为变量。
现在我们还没有给dog1的成员变量赋任何值,也就是说我们只知道dog1是一条狗,但还不知道他叫什么,不知道他几岁。我们现在在程序里给dog1设置一些数据。
public class AppMain {
public static void main(String[] args) {
// TODO Auto-generated method stub
Dog dog1 = new Dog();
dog1.name = "旺财";
dog1.age = 3;
Dog dog2 = new Dog();
dog2.name = "小强";
dog2.age = 2;
}
}
这里有一点需要说明一下,对象dog1的成员name和age没有赋过任何值的时候,他们有一个默认值。任何基础数据类型的变量,如果从来没有给这个变量赋过值的话,JVM会给变量分配一个默认值。Int类型的默认值是0,string类型默认值是空字符串,空字符串用一对双引号表示。其它数据类型的默认值我们以后会慢慢接触到。如果给对象dog1的成员变量赋值,比如dog1.name=“旺财”;默认值就会更改为“旺财“。
刚才我们分析的是dog1对象在实例化时成员变量的内存结构,现在我们再分析一下成员方法的内存分配情况。JVM将成员变量存放在堆内存中,成员方法存放在另一块内存空间中,叫做“方法区” 这块区域存放了Dog类的信息,其中就包括成员方法。方法区中的成员方法会和堆内存中的成员变量关联对应起来吗?当然会,JVM会帮助我们完成这个工作。JVM会按照一定机制将这块方法区中的方法与堆内存区中的成员变量相互关联起来,当执行dog1.name = “旺财”这条语句的时候,会将字符串“旺财”送到dog1的”堆内存“区的成员变量name中,当执行dog1.Introduce()这条语句的时候,会调用dog1的方法区中introduce方法。注意:下面这几条语句都是错误的语句,大家想一想为社么错误。

这就是单个对象的实例化过程。这种用图形的方式描述对象的内存结构,对理解类和对象的一些重要概念有很大帮助,希望大家能够理解并掌握这种画图方法,以后如果遇到难以理解的问题,可以按这个方法自己画一画,往往很容易就能帮助我们理清思路。
现在再看看新增dog2对象的内存结构。
dog1对象表示的是堆内存中创建出来的一个Dog对象,成员变量在堆内存,方法在方法区。现在看看新增一个dog2对象时发生了什么。与刚才的分析一样,栈内存会有一个对象名称dog2,代表的是在堆内存中创建的另一个Dog对象,成员变量放在堆内存中,这块成员变量区域与上面dog1的内存区域是两个不同的区域,dog2的成员变量与dog1的成员变量之间相互独立,互不影响。这就叫做每个对象都拥有一份成员变量的拷贝。
然而,dog2的方法区却和dog1的方法区是共用的。也就是说,introduce方法只有一份,dog1.introduce()语句所调用的代码和dog2.introduce()语句所调用的代码是同一份代码,但是为什么输出结果不一样呢?原因是在程序运行过程中,JVM可以根据是由哪个对象发起对introduce方法的调用,方法中所用到的成员变量数据就使用哪个对象的数据,这样,对象dog1调用introduce(),方法里的name和age用的是dog1的name和p的age,而dog2调用introduce时,方法里的name和age用的就是dog2对象的name和age。
搞清楚上述概念后,剩余的代码请读者自己完成。
Java入门:创建多个对象的更多相关文章
- 《Effective Java》—— 创建与销毁对象
本篇主要总结的是<Effecticve Java>中关于创建和销毁对象的内容. 比如: 何时以及如何创建对象 何时以及如何避免创建对象 如何确保及时销毁 如何管理对象销毁前的清理动作 考虑 ...
- 和我一起学Effective Java之创建和销毁对象
前言 主要学习创建和销毁对象: 1.何时以及如何创建对象 2.何时以及如何避免创建对象 3.如何确保它们能够适时地销毁 4.如何管理对象销毁之前必须进行的清理动作 正文 一.用静态工厂方法代替构造器 ...
- Effective Java - [2. 创建与销毁对象]
让对象的创建与销毁在掌控中. Item 1: 使用静态工厂方法而非使用构造函数 public static Boolean valueOf(boolean b) { return b ? Boolea ...
- Java入门 - 语言基础 - 04.对象和类
原文地址:http://www.work100.net/training/java-object-class.html 更多教程:光束云 - 免费课程 对象和类 序号 文内章节 视频 1 概述 2 J ...
- Java进阶 创建和销毁对象
最近准备写点Javase的东西,希望可以帮助大家写出更好的代码. 1.给不可实例化的类提供私有构造器 比如:每个项目中都有很多工具类,提供了很多static类型的方法供大家使用,谁也不希望看到下面的代 ...
- Java入门系列-11-类和对象
这篇文章为你搞懂类和对象的使用 对象:用来描述客观事物的实体,由一组属性和方法组成,万物皆对象. 属性:就是对象的特征,像身高.体重.颜色 方法:对象的行为,如跑.跳 类:类是模子,定义对象将会拥有的 ...
- Java入门笔记 03-面向对象(下)
介绍:除了前面介绍的关于类.对象的基本语法之外,下面继续介绍Java面向对象的特性. 一. 包装类: 从JDK 1.5以后,Java就提供了自动装箱和自动拆箱操作,即: 自动装箱:将一个基本类型的变量 ...
- Java入门笔记 03-面向对象(上)
介绍:Java是面向对象的程序设计语言,类是面向对象的重要内容,可以把类当成是一种自定义类型,可以使用类来定义变量,这种类型的变量统称为引用变量.也就是说,所有类都是引用类型.Java也支持面向对象的 ...
- 针对安卓java入门:类和对象
定义类 class Dog { String name; int age; void jump(){ } } 生成对象: public class Test { public static void ...
- 【读书笔记】《Effective Java》——创建和销毁对象
Item 1. 考虑用静态工厂方法替代构造器 获得一个类的实例时我们都会采取一个共有的构造器.Foo x = new Foo(): 同时我们应该掌握另一种方法就是静态工厂方法(static facto ...
随机推荐
- BugPhobia开发篇章:Alaph阶段Scurm Meeting
[github] https://github.com/bugphobia/XuebaOnline 0x01 :目录与摘要 If you weeped for the missing sunset ...
- 20172329 2018-2019 《Java软件结构与数据结构》实验三报告
20172329 2018-2019-2 <Java软件结构与数据结构>实验三报告 课程:<Java软件结构与数据结构> 班级: 1723 姓名: 王文彬 学号:2017232 ...
- cnblogs用户体验及建议
一.是否提供了良好的体验给用户(同时提供价值)? 我觉得博客园还是给用户提供了良好的用户体验的,它可以从用户的角度考虑,用户在注册的时候,用户自己在设置用户名和密码的时候,如果与他人重复会有提示,而且 ...
- 课堂讨论—Alpha版总结会议
我们在课堂上针对第一阶段冲刺过程中存在的问题,展开了激烈的讨论,并投票选出需要改进的最主要三个问题. 有图有真相:
- 软工实践-Beta 冲刺 (4/7)
队名:起床一起肝活队 组长博客:博客链接 作业博客:班级博客本次作业的链接 组员情况 组员1(队长):白晨曦 过去两天完成了哪些任务 描述: 1.界面的修改与完善 展示GitHub当日代码/文档签入记 ...
- ubuntu16.04+cuda8.0+caffe
=========== 如果出现nvidia-smi failed to communicate with nvidia driver,循环登录情况,则: sudo apt-get remove -- ...
- 微信小程序之Flex布局
微信小程序页面布局方式采用的是Flex布局.Flex布局,是W3c在2009年提出的一种新的方案,可以简便,完整,响应式的实现各种页面布局.Flex布局提供了元素在容器中的对齐,方向以及顺序,甚至他们 ...
- iOS- 如何使用Alcatraz来高效的管理Xcode-Plugin(Xcode插件)
1.前言 相信各位iOS攻城师用的Xocde的快捷插件也不少,今天向大家分享一款能高效快捷的管理Xcode-Plugin的软件<Alcatraz>,自己亲自体验后,爱不释手. (这里用 ...
- 动态语句SQL语句写法
/*************************************************************************************************** ...
- 正确的姿势解决IE弹出证书错误页面
在遇到IE证书问题时,正确的解法是安装证书到受信任的储存区 1.继续浏览此网站 2.进入页面后,点击地址栏的证书错误,查看证书 3.安装,设置安装到受信任的颁发机构 4.OK