Java面向对象(二):成员变量—OOP中的内存管理—构造函数
第一节 成员变量
1.1成员变量与局部变量
成员变量:声明在类下面,方法外面;作用于整个类中;
局部变量:声明在方法下面,作用于方法下面。
1.2 成员变量默认值
成员变量的默认值和数组的默认值一样:
整数类型:0
浮点类型:0.0
字符类型:\u0000
布尔类型:false
字符串类型:null
1.3 成员变量和局部变量的区别
1.从声明的位置: 局部变量声明在方法中,成员变量声明在类下面。
2.从默认值方面: 局部变量没有默认值,成员变量有默认值。
3.从生命周期来说: 局部变量随着方法的调用而开辟存储空间,方法调用结束。
释放存储空间,成员变量随着对象的消失而消失。
4.从存储位置方面: 局部变量存储在栈内存,成员变量存储在堆内存 。
第二节 面向对象中JVM内存管理
2.1 类文件名
类文件是以.java为后缀的代码文件,在每个类文件中最多只允许出现一个public类,
当有public类的时候类文件的名称必须和public类的名称相同,若不存在public,
则类文件的名称可以为任意的名称(以数字开头的名称是不允许的)。
2.2 栈内存、堆内存与方法区
JAVA的JVM的内存可分为3个区:堆(heap)、栈(stack)和方法区(method) 。
2.2.1堆区:
1.存储的是对象和成员变量。
2.JVM只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身
2.2.2栈区:
1.每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中
2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
3.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
2.2.3方法区:
1.又叫静态区,跟堆一样,被所有的线程共享。
存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据 (重点)
2.方法区中包含的都是在整个程序中唯一的元素,如class,static变量。
2.3 创建对象过程中内存中各类数据的执行情况
运行类过程:方法区找到方法--堆中实例化对象--调用栈(指向堆中实例)
之前笔记存疑,确定后更新 待补充.........................
总结:
栈内存:基本的数据类型、对象的引用;
堆内存:一切new出来的对象,成员变量;
方法区:class文件、static变量、常量等;
参考:https://blog.csdn.net/qian520ao/article/details/78952895
第三节 构造函数
3.1 构造函数
1、意义:对成员变量(类)初始化;
2、分类:无参构造函数 有参构造函数
3.3 this关键字
在java中的作用:
1、代表本身(本类) this.成员变量
2、可以调用本类相关的构造函数
无参调有参:this(参数列表);
有参调无参:this();
备注:
1、this关键字在调用自身的构造函数时,必须放在构造函数的第一行,否则报错;
2、无参调有参,有参调无参只能存一,不能同时存在;
例程:Dog.java
3.3 构造函数的特点
1.没有返回值(不用写void)。
2.方法名必须和类名一致。
无参构造函数:
语法:
public 类名(){
方法体
}
有参构造函数:
语法:
public 类名(参数列表){
方法体
}
例程:Dog.java
1 package gouzao_this; 2 3 public class Dog { 4 5 String kind; 6 String name; 7 int age; 8 9 //无参构造函数 10 public Dog() { 11 //无参调有参,this调用自身的构造函数必须放在第一行否则会报错 12 //this("大黄","土狗",9); 13 14 //有参与无参之间的相互调用只能存在一个不能同时都存在 15 kind = "erha"; 16 name = "shagou"; 17 age = 3; 18 System.out.println("无参调用"); 19 } 20 21 //有参构造函数 22 public Dog(String name,String kind,int age) { 23 // this(); //有参调无参 24 25 //this 关键字调用类本身 26 this.name = name; 27 this.kind = kind; 28 this.age = age; 29 System.out.println("有参调用"); 30 } 31 32 public void show() { 33 System.out.println("这是条叫"+name+"的"+kind+"今年"+age+"岁"); 34 } 35 36 }
例程:测试Dog类:
1 package gouzao_this; 2 3 public class TextDog { 4 5 public static void main(String[] args) { 6 7 Dog dog1 = new Dog(); //调用无参构造函数 8 Dog dog2 = new Dog("大黄","土狗",4); 9 dog1.show(); 10 dog2.show(); 11 } 12 13 }
思考:
1.构造函数中能否有retrun关键字?
可以,只用写 return; 作为结束符;
2.有参构造函数中参数列表能否自行控制数量(数量能否不和成员变量一致)?
可以,想初始化几个变量就初始化几个变量
3. 有参构造函数和无参构造函数能够独立存在?
可以,但是最好都把它写在类中。
备注:
1、构造函数在创建对象函数时执行,即对象的创建是对类的构造函数的调用;
2、若没有创建构造函数时,系统会默认添加一个无参构造函数,new对象时会自动调用无参构造函数;
3、当添加了有参构造函数时,系统此时不会默认添加一个无参构造函数,需手动添加无参构造函数;若不添加无参构造函数,不能够创建无参对象;
练习:用面向对象的思想实现之前的双色球随机数组,要求生成随机数的最大值可以任意改变。
参考代码:
1 package gouzao_this; 2 3 import java.util.Arrays; 4 import java.util.Random; 5 6 public class DoubleColerBall { 7 8 public void getNum(int redBallNum,int blueBallNum) { 9 10 int[] redBall = new int[6]; 11 int index =0; 12 int temp = 0; 13 int blueBN = 0; 14 15 Random r = new Random(); 16 // 生成红色球的随机数 17 redBall[index++] = r.nextInt(redBallNum)+1; 18 19 loop: while(true) { 20 21 temp = r.nextInt(redBallNum)+1; 22 for(int t=0; t<redBall.length;t++) { 23 24 if(redBall[t]==temp) { 25 26 continue loop; 27 28 } 29 } //for 循环 30 31 redBall[index++] = temp; 32 if (index==6) { 33 34 break; 35 } 36 37 } 38 39 40 // 蓝色球随机数 41 blueBallNum = r.nextInt(blueBallNum)+1; 42 43 int[] Ball = Arrays.copyOf(redBall, redBall.length+1); 44 45 Ball[Ball.length-1]=blueBallNum; 46 47 System.out.println("生成的数组为:"+Arrays.toString(Ball)); 48 49 } 50 51 }
1 package gouzao_this; 2 /** 3 * 4 * @项目名称:OOPDay02m 5 * @模块功能:用面向对象的思想方法实现双色球, 6 * 要求生成随机数的最大值可以任意改变。 7 * @模块版本: 8 * @JDKVersions:JDK 8.0 9 * @author: Kanekiyi 10 */ 11 public class TextDoubleCB { 12 13 public static void main(String[] args) { 14 15 DoubleColerBall DCB1 = new DoubleColerBall(); 16 // 输入红球蓝球生成的数字最大数 17 DCB1.getNum(37,18); 18 } 19 20 }