当前位置: 首页 > ai >正文

Java类与对象的描述及内存原理

一、举例引入

        假如有一只柴犬叫小柴,今年1岁,是个男孩子,它会吃饭,会撒娇;有一只哈士奇叫小哈,今年2岁,也是个男孩子,它也会吃饭,也会撒娇;还有只白土松叫奶油,也是个男孩子,今年1岁,它也会吃饭,也会撒娇。

       如果要将以上的文字转化成Java的程序来描述,从变量和方法的角度来看,姓名,年龄,性别这些都属于变量,而吃饭,撒娇这些属于方法。那么就需要给小柴、小哈和奶油分别定义品种,姓名,年龄,性别,以及吃饭,撒娇的行为方法。这样做会产生大量的变量和方法,不仅不利于对变量和方法的管理,而且会使效率变得十分低下。

从变量和方法的角度

        既然它们都有品种,姓名,年龄,性别这些相同的特征,又有吃饭,撒娇这样相同的行为方法。那么就完全可以把相同的地方抽象提取出来,构建一个新的类别,这个新的类别具备了以上各个小狗的特征以及行为方法。当要对这个类别一个具体的事物进行描述时,就可以创建一个这个类别的对象,这个对象就已经具备了这些特征和行为。特征就作为类的属性,而行为作为类的方法。要使用和管理的时候,可以直接创建对象,并通过对象名来设置属性和方法,管理的时候只要通过管理对象就可以了,这样就可以提高编程效率了。 

从类的角度来看

       类是一种数据类型,是自己定义的数据类型;而对象就是具体描述的事物。对象诞生于类,而类可以描述对象。

        通过类可以将相同的代码总结到一起,如果要使用的时候,直接新建对象就可以了。可以提高代码的复用性;也便于维护,如果某个类需要添加新的属性,直接在类中添加相应的代码即可;而且便于管理,使用类中的属性或方法的时候直接进行相应的调用就可以了。

二、具体实现

        类的属性或叫成员变量既可以是基本数据类型,也可以是引用数据类型。

class A {int age; //基本数据类型String name;  //引用数据类型
}

上面的例子用类的形式描述成Java语言如下:

class Dog {//属性String name;int age;char gender;//吃饭的方法public void eat() {System.out.println(name + "正在吃饭");}//撒娇的方法public void spoil() {System.out.println(name + "正在撒娇");}//显示信息的方法public void showInfo() {System.out.println("name:" + name + ",age:" + age + "岁,gender:" + gender);}
}

        属性就是描述类的具体特征;方法是描述类的具体行为,构造器是对类进行初始化,在创建对象时具备基本的特征。

在main方法中创建对象并调用相应的方法:

public class Test {public static void main(String[] args) {//分别创建对象,并添加相关信息Dog d1 = new Dog();d1.name = "小柴";d1.age = 1;d1.gender = '男';Dog d2 = new Dog();d2.name = "小哈";d2.age = 2;d2.gender = '男';Dog d3 = new Dog();d3.name = "奶油";d3.age = 1;d3.gender = '男';//打印信息d1.showInfo();d2.showInfo();d3.showInfo();//调用方法d1.eat();d2.eat();d3.spoil();}
}

运行结果如下:

三、内存原理 

创建对象格式:

Dog d = new Dog();

 这里的d只是对象的引用(对象名),而new Dog()才是真正的对象。

Java内存机制:

  1. 栈:存放基本数据类型
  2. 堆:存放对象,给对象和引用数据类型开辟空间
  3. 方法区:常量池(存放字符串常量),加载类的信息(属性和方法)

当创建一个对象的时候:

  1. 先在方法区中加载类的信息;
  2. 在堆中开辟空间,此时类中的属性为初始的默认值;
  3. 将堆中的地址值返回给栈中的变量;
  4. 对属性进行初始化,将类中的属性更新为设置的值。

 以一段创建对象的代码为例:

Dog d3 = new Dog();
d3.name = "奶油";
d3.age = 1;
d3.gender = '男';

以上的内存图如下:

创建对象的内存图 

分析:

  1. main方法先进栈,然后方法区中加载Dog类的信息,包括类的属性和方法;
  2. 在堆中开辟一块空间,假设地址为0x2233,此时类中的属性值为初始的默认值,之后会把地址0x2233返回给栈中的d3,d3就通过这个地址指向堆中相应的空间;
  3. 因为字符串存储在方法区的常量池中,所以会在常量池中开辟一块空间,假设地址为0x2244,会把0x2244返回给堆中相应空间的name,所以name就通过这个地址指向常量池对应的空间中(String类型的数据并不会直接存储在堆中,而是存储在方法区的常量池中,和创建对象的原理有点类似);
  4. 之后age和gender会从初始值更新为1和'男'。

http://www.xdnf.cn/news/5991.html

相关文章:

  • 激光打印机常见打印故障简单处理意见
  • WebPageTest 多地域测试
  • ElasticSearch深入解析(十一):分页和分批统计的三种实现
  • 【AI论文】健康的大型语言模型(LLMs)?——评估大型语言模型对英国政府公共健康信息的掌握程度
  • TypeScript 知识框架
  • Python之with语句
  • 高级 Java 锁技术:超越基本同步
  • 应用探析|千眼狼PIV测量系统在职业病防治中的应用
  • idea2021创建web项目及其整合tomcat
  • RuoYi-Cloud
  • CodeBuddy 中国版 Cursor 实战:Redis+MySQL双引擎驱动〈王者荣耀〉战区排行榜
  • 阳光学院【2020下】计算机网络原理-A卷-试卷-期末考试试卷
  • 中国区adsense接收pin码,身份验证和地址验证指南
  • AD Class创建与Class应用
  • 求由无穷串构成的二进制数的值
  • 初始“协议”
  • IPD流程实战:产品开发各阶段目标、关注点和交付
  • 基于概率论与数理统计的股市预测模型研究
  • WHAT - 《成为技术领导者》思考题(第九章)
  • 【漫话机器学习系列】256.用 k-NN 填补缺失值
  • LeetCode热题100--206.反转链表--简单
  • 捌拾肆- 量子傅里叶变换 (2)
  • 编译docker版openresty
  • MySQL——数据类型表的约束
  • 无线定位之四 SX1302 网关源码 thread_jit 线程详解
  • 道通EVO MAX系列无人机-支持二次开发
  • Springboot实现重试机制
  • 工具学习_VirusTotal使用
  • 集成钉钉消息推送功能
  • 软件I2C