`

疯狂java基础功16讲(2)------对象与内存控制

阅读更多
Java内存管理分为两个方面:内存分配和内存回收。
内存分配特指创建Java对象时JVM为该对象在堆内存中所分配的内存空间。
内存回收指的是当该Java对象失去引用,变成垃圾时,JVM的垃圾回收机制自动清理该对象,并回收该对象所占用的内存。

由于JVM垃圾回收机制由一条后台线程完成,本身非常消耗性能的,因此如果肆无忌惮地创建对象,让系统分配内存,这样会有两个坏处:
A:不断分配内存使得系统中可用内存减少,从而降低程序运行性能。
B:大量已分配内存的回收使得垃圾回收的负担加重,降低程序的运行性能。

本课主要介绍
   创建Java对象时的内存分配细节, 即内存管理管理中关于内存分配方面知识。


一、实例变量与类变量
  
   Java程序的变量大体可分为成员变量和局部变量。
   1、局部变量,局部变量可以分为3类。
       A:形参,在方法签名中定义的局部变量,由方法调用者为其赋值,随方法结束消亡
       B:方法内的局部变量,在方法内定义,在方法内对其进行显示初始化,随方法结束消亡。
       C:代码块内的局部变量,在代码块内定主,在代码块内对其进行显示初始化,随代码块结束而消亡。
    局部变量的作用时间很短暂,它们都被存储在方法的栈内存中。 

   2、成员变量,成员变量可以分为非静态变量(实例变量)或静态变量(类变量)
       A:非静态变量,没有使用static修饰符修饰的变量
       B:静态变量,使用了static修饰

public class TwoObject {
	/*1
	//下面代码将提示:非法向前引用
	int num1 = num2 + 2 ;
	int num2 = 3 ;
	*/

	/*2
         //下面代码将提示:非法向前引用
	static int num1 = num2 + 1 ;
	static int num2 = 2 ;
	*/
	
	/*3
	 * num2的初始化时机总是位于num1之前
	 */
	//下面代码完全正常
	int num1 = num2 +1 ;
	static int num2 = 2 ;
	
}


  
   A、实例变量和类变量
      使用static修饰的成员变量为类变量,属于该类本身;
      没有使用static修饰的成员变量为实例变量,属于该类的实例。

   由于同一人JVM内每个类只对应一个Class对象,因此同一个JVM内的一个类变量只需一块内存空间;
   但对于实例变量而言,每创建一次实例,就需要为实例变量分配一块内存空间。

   实例变量属于对象,类变量属于类的特性。
 
public class TwoObject2 {
	public static void main(String[] args) {
		//类变量属于该类本身,只要该类初始化完成,程序即可使用类变量
		Person.eyeNum = 2 ;
		//通过Person类访问eyeNum类变量
		System.out.println("Person 的eyeNum属性:"+Person.eyeNum);
		
		//创建 1个Person对象
		Person p = new Person();
		p.name = "孙悟空";
		p.age = 500;
		//通过p访问Person类的eyeNum类变量
		System.out.println("p.eyeNum="+p.eyeNum);
		p.info();
		//创建第2个Person对象
		Person p2 = new Person();
		p2.name = "唐僧";
		p2.age = 20 ;
		//通过p2修改Person类变量eyeNum
		p2.eyeNum = 3 ;
		System.out.println("p.eyeNum="+p.eyeNum);
		System.out.println("p2.eyeNum="+p2.eyeNum);
		System.out.println("Person.eyeNum"+Person.eyeNum);
		
	}
}

class Person{
	String name ;
	int age ;
	static int eyeNum;
	public void info(){
		System.out.println("name="+name+" age="+age);
	}
}

  

   

   B、实例变量的初始化时机

    对于实例变量而言,它属于Java对象本身,每次程序创建Java对象时都需要为实例变量分配内存空间,并执行初始化。
    程序可以在3个地方为实例变量执行初始化:
       A:定义实例变量时指定初始值;
       B:非静态初始化块中对实例变量指定初始值;
       C:构造器中对实例变量指定初始值;
    A和B两种方式比C种更早执行,A和B的执行顺序与它们在程序中的排列顺序相同。

    定义实例变量指定初始值 、初始化块中指定初始值,地位是平等的,当经过编译器处理后,它们都将被提取到构造器中。并总是位于构造器的所有语句之前;合并后,两种语句的顺序保持它们在源代码中的顺序。

package com.crazyjava;

public class TwoObject3 {
	public static void main(String[] args) {
		Cat cat = new Cat("tom",2);
		System.out.println(cat);
		
	}
}
class Cat{
	String name ;
	int age ;
	public Cat(String name,int age) {
		this.name = name ;
		this.age = age;
	}
	{
		weigth = 2.0 ;
	}
	double weigth = 2.3;
	@Override
	public String toString() {
		return "Cat[name="+name+",age="+age+",weigth="+weigth+"]";
	}
	
}

Output: Cat[name=tom,age=2,weigth=2.3]



   C、类变量初始化时机

       类变量属于Java类本身,只有当程序初始化该Java类时才会为该类分配内存空间,并执行初始化。

       程序可以在2个地方为类变量来执行初始化:
          A:定义类变量时指定初始值
          B:静态初始化块中对类变量指定初始值
       这两种方式的顺序与它们在源程序中排列顺序相同。

package com.crazyjava;

public class TwoObject4 {
	//定义count类变量,定义时指定初始值
	static int count = 2; 
	//通过static块为name指定初始值
	static{
		System.out.println("初始化块");
		name = "Java编程";
	}
	static String name = "疯狂Java讲义";
	
	public static void main(String[] args) {
		System.out.println("count="+count+" name="+name);
	}
}

Output:
初始化块
count=2 name=疯狂Java讲义




二、父类构造器

当创建任何对象时,程序总会先依次调用每个父类非静态初始化块、父类构造器(总是从Object开始)执行初始化,最后才调用本类的非静态初始化块、构造器执行初始化。


三、父子实例的内存控制







四、final修饰符




分享到:
评论

相关推荐

    疯狂Java:突破程序员基本功的16课-高清扫描版带书签

    介绍了Java的对象、数组的内存分配,介绍了常见集合的实现细节、内存回收的细节、表达式、流程控制、面向对象、异常的“陷阱”,常用的数据结构和算法的实现以及其他基础的内容,值得细细阅读。

    《疯狂Java 突破程序员基本功的16课》PDF版本下载.txt

    根据提供的文件信息,我们可以推断出这是一本关于Java编程技术的书籍——《疯狂Java突破程序员基本功的16课》。尽管没有提供具体的章节内容,但基于书名及其描述,我们可以合理推测这本书的主要内容是帮助程序员提升...

    疯狂JAVA之学习笔记(1--15)

    - **堆**:动态分配内存区域,用于存放对象实例。 - **方法区**:存储类信息、常量、静态变量等数据。 #### 4. JVM 的抽象架构 JVM 设计为一个抽象的计算机模型,可以实现为软件或硬件。它的主要目标是在任何操作...

    疯狂Java:突破程序员基本功16课pdf+源代码

    《疯狂Java:突破程序员基本功16课》是一本针对Java程序员进阶的教程,旨在提升读者在编程领域的技能和专业素养。这本书结合了理论与实践,通过16个关键课程,深入讲解了Java编程的核心概念和技术。源代码的提供使得...

    疯狂JAVA讲义光盘资料.zip

    《疯狂JAVA讲义》是一本深受Java学习者喜爱的教材,其光盘资料包含了丰富的学习资源,涵盖了Java开发语言的基础到高级,以及后端开发的相关技术。这份压缩包中的资料无疑是学习和提升Java技能的宝贵财富。以下是这些...

    疯狂java讲义06 电子版 pdf

    标题“疯狂java讲义06 电子版 pdf”暗示这是一本深入讲解Java语言的电子书籍,针对的是对Java有一定基础并希望进一步提高的读者。从描述和标签中我们无法获取更多信息,但可以推测这本书会详细地介绍Java的核心概念...

    最新版---疯狂java讲义

    《疯狂Java讲义》是一本深受Java学习者喜爱的经典教程,它全面且深入地涵盖了Java编程的各个方面。这本书旨在帮助有志于IT行业的读者提升Java技术能力,为他们的职业生涯打下坚实的基础。以下是对该书内容的详细解读...

    疯狂JAVA:突破程序员基本功的16课 源码

    在《疯狂JAVA:突破程序员基本功的16课》中,作者深入浅出地探讨了Java编程中的核心概念和技术,旨在提升程序员的基本技能和解决问题的能力。以下是对这些知识点的详细阐述: 1. **Java基础**:Java是一种面向对象...

    疯狂Java讲义精粹随书光盘

    《疯狂Java讲义精粹随书光盘》是学习Java编程的重要参考资料,它包含了大量关于Java技术的精华内容。这个光盘的主体是《疯狂Java讲义》这本书的电子版,该书由资深Java专家撰写,旨在帮助读者深入理解Java语言,并...

    疯狂java讲义-光盘内容

    《疯狂Java讲义》是一本深受Java初学者和进阶者喜爱的教材,它全面而深入地探讨了Java编程语言的各种核心概念和技术。光盘内容通常包含书中提及的实例源代码、练习题解答以及可能的视频教程等补充资料,旨在帮助读者...

    java疯狂讲义,PDF版最新全版

    这份讲义可能是由一位资深Java开发人员或者教育工作者编写,旨在帮助初学者乃至有一定基础的学习者深入理解Java语言,并掌握其核心概念与高级特性。下面将对这份讲义可能涵盖的重要知识点进行总结和解析。 ### 1. ...

    疯狂Java_突破程序员基本功的16课.pdf

    《疯狂Java_突破程序员基本功的16课》是一本专为Java程序员设计的技能提升指南,旨在通过16个关键课程帮助读者巩固和提升Java编程基础。这本书深入浅出地探讨了Java语言的核心概念和技术,是提升Java编程能力的理想...

    疯狂java讲义2代码

    《疯狂Java讲义2》是一本深度探讨Java编程技术的书籍,其代码示例部分包含了大量实战性的程序,旨在帮助读者深入理解Java语言的核心概念、语法特性以及在实际开发中的应用。下面,我们将针对这个主题,结合代码示例...

    疯狂Java面试题(疯狂Java讲义精粹附赠).pdf

    "疯狂Java面试题(疯狂Java讲义精粹附赠).pdf" 本资源是关于Java面试题的集合,涵盖了Java核心技术部分的面试题,包括Java基本语法、面向对象、Java常用API、Java集合框架、注解、泛型、输入/输出、多线程、网络...

    疯狂Java面试题

    【疯狂Java面试题】是针对Java开发者的一份重要的学习资源,源自《疯狂Java讲义》第四版中的原版面试题目。这份资料集涵盖了广泛的Java编程和相关技术的知识点,旨在帮助求职者准备Java开发岗位的面试,同时也适用于...

    疯狂java讲义目录 电子版 pdf

    以上是对《疯狂Java讲义》部分内容的知识点总结,涵盖了 Java 语言的基础概念、面向对象编程的基础、数据类型与运算符的使用、流程控制语句以及数组的相关知识。通过对这些知识点的学习,读者可以建立起 Java 编程的...

    疯狂JAVA面试题

    标题《疯狂JAVA面试题》所对应的书籍内容涉及了大量关于Java的知识点。这些知识点是求职者在面试中经常遇到的问题。这本书不仅包含了Java的核心技术,而且还涵盖了Java编程语言的基础语法,面向对象编程,Java集合...

    疯狂JAVA讲义_.pdf

    “疯狂JAVA讲义”作为一份详实的Java教学资源,涵盖了Java编程的各个方面,从基础语法到高级特性,旨在帮助学习者全面掌握Java编程技能。无论是初学者还是有一定经验的程序员,都能从中获得有价值的知识。然而,由于...

    疯狂java讲义 程序源码

    - 序列化与反序列化:Java对象如何转换为字节流,便于存储或网络传输。 5. **多线程** - Thread类和Runnable接口:创建和管理线程的基本方式。 - 线程同步:synchronized关键字,wait()、notify()和notifyAll()...

Global site tag (gtag.js) - Google Analytics