java基础四 [构造器和垃圾回收](阅读Head First Java记录)

本章讲解了对象的创建到被回收的过程,讲述了对象的生命周期

堆(heap)与栈(stack)

实例变量:实例变量是只声明在类下,方法外的变量(实例变量默认值为0/0.0/false,引用的默认值为null)

局部变量:声明在方法中的变量,或方法中的参数。又被成为栈变量

例如:

public class test{

int size;

public void foof(int a){

int b;

barf()

}

public void barf(){

Duck d =new Duck(24);

}

}

上面的例子中,

size为实例变量,每个实例都会有一个;

a和b为局部变量

d也是局部变量,但是非primitive(int等)变量,是一个对象引用变量。

放在堆(heap)上的:实例变量放在堆上,所有对象都会在堆上。java会根据实例变量的所需空间来进行分配(primitive的根据大小来分配,引用变量如果实例化了就将实例化的对象也放到堆上,如果没有就只放一个引用量)

放在栈(stack)上的:局部变量、被调用的方法。当前调用的方法会在栈顶显示(新调用的方法从栈顶插入)。

例如:上面的例子我们去调用

test a = new test();

a.foo()

那么堆和栈的情况如下:

构造函数

构造函数

使用new关键字时执行的程序代码,会创建一个对象实例,所有类都有一个构造含数据,如果没写编译器会给写一个默认的构造函数(如果自己建了构造函数,编译器不会帮忙创建构造函数)

public class Duck{

public Duck(){

}

}

构造函数名字与类名相同;且没有任何返回类型。

构造函数可以用于初始化对象的状态

重载构造函数

一个类可以存在多个构造函数,但是必须参数的个数或类型不同(与参数名无关),就和重载一样,叫做重载构造函数

例如:下面例子的重载构造函数都是合理的

public class mushroom{

public mushroom(){}

public mushroom(int size,boolean isMagic){}

public mushroom(boolean isMagic,int size){}

}

父类的构造函数

子类对象包含自己和父类的实例变量,创建子类的对象时,所有继承下来的构造函数都会被执行

构造函数执行时,第一件事去执行它的父类的构造函数,这会连锁到Object这个类为止,这个过程被称为“构造函数链”。所以最终展示的效果是从Object到下的父类一层层的调用(堆栈,先进后出)

子类调用父类的构造函数使用super(),如果没加,编译器会自动给加上super(),super()放在子类构造函数的第一行

如果调用父类带参数的构造函数,子类的构造函数内要包含这个参数,且用super(参数)来调用

下面是调用被带参数和带参数的父类构造函数的方法。当然不带参数的调用不写super()也可以,编译器会自动加上

public class hippo extends animal{

public hippo(){

super()

}

public hippo(String name){

super(name)

}

}

this()

this指对象本身,只能用在构造函数中,放在第一行,所以this()和super()只能选择一个

使用this()来从某个构造函数调用同一个类中另外一个构造函数

例如下面的例子:

class mini extends car{

Color color;

public min(){

this(Color.Red)  //实际调用public mini(Color c)构造函数

}

public min(Color c);

super("mini")

color=c;

}

对象的生命周期

对象的生命周期取决于引用它的“引用”,如果引用还在就活者,当最后一个引用消失了就变成可回收的

局部变量:方法中的局部变量的作用域只在声明它的方法中,方法调用完毕后局部变量回收(方法执行完毕会从堆栈中弹出),当方法A调用方法B时,方法A中的局部变量暂停保存值,当执行完B调回A时才继续活动

引用变量:引用变量与局部变量相同,只在处于范围内的时候能被引用,参考局部变量

实例变量:实例变量的作用域是它所属的类,如果对象还活着,实例变量就也活着,如果对象被释放了,也就释放了(实例变量和对象一起生活在堆上)

三种释放对象的方法:

1.将引用变量放在方法中,方法结束后也就被释放了

void go(){

Life z=new Life)()

}

2.重新赋值新对象

Life z=new Life();

z=new Life(); //此时第一个对象在z被赋值后可回收

3.直接将引用赋值为null

Life z= new Life();

z=null;

注意:如果对象A被其他对象B等引用了,通过A=null或重新给A分配内存也不能释放该内存,因为该快内存还再被B占用

时间: 2024-08-19 06:21:00

java基础四 [构造器和垃圾回收](阅读Head First Java记录)的相关文章

java基础十一[远程部署的RMI](阅读Head First Java记录)

方法的调用都是发生在相同堆上的两个对象之间(同一台机器的Java虚拟机),如果想要调用另一台机器上的对象,可以通过Socket进行输入/输出. 远程过程调用需要创建出4种东西:服务器.客户端.服务器辅助设施.客户端辅助设施 RMI Java的JMI提供客户端和服务器端的辅助设施对象(stub和skeleton,现在实际只用stub文件,客户端和服务端用一个) 辅助设施是实际执行通信的对象,他会让客户端感觉在调用本机,实际上辅助设施类似于代理,将客户端传送的信息通过Socket连接发送给服务端辅助

接口,构造器与垃圾回收机制,对像的生命周期。非静态方法与静态方法。

java不充许多继承是,为了避免“致命方块”的出现例如 B继承A,C继承A. C和C里面都有play()方法 .现在D继承了B,C 想想D.play()调用 的是哪个play()呢,这就是问题所在. 所以java提供了接口来解决此问题. 问:接口并不是真正的多重继承,因为你无法在它里面实现程序代码,不是吗?如果是这样,那还要接口做什么? 答:多态,多态,多态.接口有无比的适用性,若你以接口取代具体的子类或抽象的父类作为参数或返回类型,则你就可以传入任何有实现该接口的东西.这么说吧,使用接口你就可

(转)《深入理解java虚拟机》学习笔记3——垃圾回收算法

Java虚拟机的内存区域中,程序计数器.虚拟机栈和本地方法栈三个区域是线程私有的,随线程生而生,随线程灭而灭:栈中的栈帧随着方法的进入和退出而进行入栈和出栈操作,每个栈帧中分配多少内存基本上是在类结构确定下来时就已知的,因此这三个区域的内存分配和回收都具有确定性.垃圾回收重点关注的是堆和方法区部分的内存. 常用的垃圾回收算法有: (1).引用计数算法: 给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器都为0的对象就是不再被使用的,垃

Java基础四

Java基础四 一.Switch语句 二.if和switch区别 推荐使用if 三.函数 Java中的函数和方法是同一个词 四.数组 4.1.数组常见错误 五.内存机制 六.转换成十六进制 移位 &操作 6.2 查表法求十六进制 查表法很多时候都非常好用,这样就非常好了,真的非常好用 算的时候直接移四位,我喜欢,我觉得以后可以多做移位运算,真的是简单方便 6.3 查表法求星期几

Java 中的四种引用及垃圾回收策略

Java 中有四种引用:强引用.软引用.弱引用.虚引用: 其主要区别在于垃圾回收时是否进行回收: 1.强引用 使用最普遍的引用.如果一个对象具有强引用,那就 类似于必不可少的生活用品,垃圾回收器绝不会回收它.当内存空 间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足问题. 2.软引用(SoftReference) 如果一个对象只具有软引用,那就类似于可有可物的生活用品.如果内存空间足够,垃圾回收器就不会回收它,如果

Java中的内存分配与垃圾回收

一.内存分配 Java程序运行时的内存分配,按照JVM规范,包括以下几个区域:程序计数器.虚拟机栈.本地方法栈.方法区.堆.其中,前三个是线程私有的,与线程生命周期相同,线程退出内存自动回收:后两者是所有线程共享内存的,只在垃圾回收机制被触发时,被动回收. * 程序计数器,内存区域极小,是当前线程的字节码执行行号指示器: * 虚拟机栈.本地方法栈,即平时所说的“栈”,是虚拟机用来执行方法(包括Java.非Java方法)时,使用的临时内存空间,用来存储当前方法.局部变量等,全部基本类型变量,以及类

JVM虚拟机(四):JVM 垃圾回收机制概念及其算法

垃圾回收概念和其算法 谈到垃圾回收(Garbage Collection)GC,需要先澄清什么是垃圾,类比日常生活中的垃圾,我们会把他们丢入垃圾箱,然后倒掉.GC中的垃圾,特指存于内存中.不会再被使用的对象,儿回收就是相当于把垃圾"倒掉".垃圾回收有很多中算法:如 引用计数法.标记压缩法.复制算法.分代.分区的思想. 垃圾收集算法 引用计数法:就是个比较古老而经典的垃圾收集算法,其核心就是在对象被其他所引用计数器加1,而当引用时效时则减1,但是这种方式有非常严重的问题:无法处理循环引用

深入理解JAVA虚拟机之JVM性能篇---垃圾回收

一.基本垃圾回收算法 1. 按基本回收策略分 1) 引用计数(Reference Counting)  对象增加一个引用,即增加一个计数,删除一个引用则减少一个计数.垃圾回收时,只用收集计数为0的对象.此算法最致命的是无法处理循环引用的问题. 2)标记-清除(Mark-Sweep)  执行分两阶段.第一阶段从引用根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除. 缺点是此算法需要暂停整个应用,同时会产生内存碎片. 3)复制(Copying) 把内存空间划为两个相等的区域,每

Java进阶之内存管理与垃圾回收

Java是在JVM所虚拟出的内存环境中运行的.内存分为栈(stack)和堆(heap)两部分.我们将分别考察这两个区域. 栈 在Java中,JVM中的栈记录了线程的方法调用.每个线程拥有一个栈.在某个线程的运行过程中,如果有新的方法调用,那么该线程对应的栈就会增加一个存储单元,即帧(frame).在frame中,保存有该方法调用的参数.局部变量和返回地址. 调用栈 Java的参数和局部变量只能是基本类型的变量(比如int),或者对象的引用(reference).因此,在栈中,只保存有基本类型的变