一、java的类变量和实例变量:
java中的变量可分成两种:成员变量和局部变量。

1、局部变量包括以下几类:

  • 方法内的局部变量:作用域为方法体。
  • 代码块内的局部变量:作用域为代码块
  • 形参:方法内的形式参数,作用域为方法体。
注意:局部变量的生存期很短,被存储在方法的栈内存之中。


2、成员变量:类体内定义的变量,使用static修饰的成员变量称为
静态变量或者类变量。

没有被static修饰的成员变量称为
实例变量。

注意1:static关键字的用法

static可以修饰的部分包括:成员变量、方法、内部类、初始化代码块、内部枚举类。如果使用static修饰,这些成

员就属于类本身,否则属于类实例。

注意2:Java中的前向引用。

一般看来,java没有规定定义成员变量时要有先后顺序。但Java要求定义成员变量时必须采用合法的前向引用。

package com.beijng.object;

public class Object01 {

        //a变量在b变量没定义之前就引用它,属于非法前向引用

int  a = b + 1;
int b = 2;
}

同样,两个类变量也不允许前向引用。如下

public class Object02 {

        //属于非法前向引用
static int a = b + 1;
static int b = 2;
}


但是,一个实例变量总是可以引用类变量。如下
public class Object01 {

        //完全正常

 int  a = b + 1;
static int b = 2;
}

总结:
(1)b是类变量,a是实例变量,在java中,类变量的初始化总是在实例变量的初始化之前。

(2)在同一个JVM中,一个类对应一个Class对象,因此同一个JVM的一个类的类变量只需要一块内存空间。

但每个类可以创建多个Java对象。每创建一个Java对象,对象的实例变量就会被分配一块内存空间。

二、实例变量的初始化

1、实例变量的初始化有三种情况

  • 定义实例变量时指定初始值
  • 非静态初始化块中为实例变量指定初始值
  • 构造方法中对实例变量指定初始值
需要注意的是:第1、2中情况比第3中情况更早执行,1、2两种情况的执行顺序与它们在源程序中的排列顺序相同。


示例如下:
 
package com.beijng.object;

public class User {

String username;
String password;
public User(String username,String password){
System.out.println("执行构造方法");
this.username = username;
this.password = password;
}
{
System.out.println("执行非静态初始化块");
age = 18;
}
//定义时指定初始值
int age =20;
public String toString(){
return "username="+username+",password="+password+",age="+age;
}
public static void main(String[] args){
User user1 = new User("xiaoming","123");
System.out.println(user1);
}
}

 

———————————————————————————————————————————————————执行非静态初始化块
执行构造方法
username=xiaoming,password=123,age=20


其实,
定义实例变量指定的初始值、初始化块中为实例变量指定初始值的语句地位是平等的,当经过编译器处理后,它

们都被提取到构造方法中:

示例如下:

package com.beijng.object;

public class JavapToolTest {

int a = 30;
{
a = 31;
}
public JavapToolTest(){
System.out.println(a);
}
public JavapToolTest(String b){
System.out.println(b);
} }

使用命令:javap -c JavapToolTest 可以查看Java编译器对JavapToolTest做的处理,可以显示每个方法具体

的字节码。

如下图中,构造方法JavapToolTest()和JavapToolTest(String name)中都包含了初始化实例变量

语句。

 




三、类变量的初始化

1、类变量属于Java类本身,程序初始化Java类时会为类变量分配内存空间,执行初始化。

可以在定义类变量时指定初始值,或者在静态初始化块中为类变量指定初始值。

2、程序初始化过程:分成2个阶段

(1)系统为程序的类变量分配内存空间

(2)按初始化代码(定义时指定初始值和初始化块中执定初始值)的排列顺序对类变量执行初始化

3、示例省略

四、父类构造器

1、当创建Java对象时,程序总是会依次调用每个父类非静态初始化块、父类构造方法(总是从Object类开始)执行

初始化,最后才调用本类的非静态初始化块、构造方法执行初始化。

2、
Java对象是在构造方法中创建的吗?

示例如下:

package com.beijng.object;
class Base {
private int i = 2;
public Base(){
System.out.println(this.i);//输出2
this.display();
}
public void display(){
System.out.println(i);//输出0
}
} class Derived extends Base {
private int i = 22;
public Derived(){
i = 222;
}
public void display(){
System.out.println(i);
}
} public class ConstructorTest { public static void main(String[] args) {
new Derived();
} }



注解
:(1)构造方法只是负责对Java对象实例变量进行初始化(即赋予初始值),在执行构造方法之前,该对象所占

用的内
存已经被分配了,这些内存里都默认是控制,基本类型变量的默认值是0或false,引用类型变量的默认值都是

null.  

(2)所以在程序执行new Derived()时,系统先为Derived对象分配内存空间,此时系统内存需要为Derived

对象分配两块内存,一个存放属于Base类定义的i实例变量,一个存放属于Derived类定义的i实例变量,此时这两个

实例变量的值都为0. 然后,在执行Derived类的构造方法之前,首先会执行Base类的构造方法,把Base的i变量赋

值为2,接着执行this.display(),
问题出现了?this代表哪个类的对象呢?

注意:当this在构造方法中时,this代表正在创建的Java对象,此时情况是:this位于Base构造方法内,但是这些

代码实际放在Derived的构造方法内执行,即
Derived的构造方法隐式调用了Base类的构造方法,所以此时this代表

的应该是
Derived对象,而不是Base对象。


(3)当变量的编译时类型和运行时类型不同时,通过该变量访问它引用的对象的实例变量时,该实例变量的值由声明

该变量的类型决定。但是通过该变量调用它引用对象的实例方法时,该方法行为将由它实际所引用的对象决定。

所以,当程序访问this.i时,
this虽然代表
Derived对象,但是它位于Base构造方法中,它的编译类型是Base,

所以就会访问Base类中定义个i实例变量,即输出2.  但是执行this.display()时,则实际表现出
Derived对象

的行为,即输出
Derived对象的i实例变量,也就是0.















(二)Java对象与内存控制的更多相关文章

  1. Java 对象及其内存控制

    作者:禅楼望月(http://www.cnblogs.com/yaoyinglong) 更新:其实这里有好多的变戏法,只要你理解了他们在JVM的中的实现机制,就豁然开朗了.有时间我会把这些变戏法的东西 ...

  2. JAVA对象与内存控制

    1.1 实例变量和类变量 成员变量和局部变量: 局部变量分为三大类: 1)形参:在方法签名中定义的局部变量,由方法调用者为其赋值,随方法的结束而消亡. 2)方法内的局部变量:在方法内定义的局部变量,随 ...

  3. JVM总结-java对象的内存布局

    在 Java 程序中,我们拥有多种新建对象的方式.除了最为常见的 new 语句之外,我们还可以通过反射机制.Object.clone 方法.反序列化以及 Unsafe.allocateInstance ...

  4. 10 Java 对象的内存布局

    Java 创建对象的方式 1:new 语句和反射机制创建.该方式会调用类的构造器,同时满足诸多约束.如果一个类没有构造器的话,Java 编译器会自动添加一个无参数的构造器.子类的构造器需要调用父类的构 ...

  5. Java对象的内存布局以及对象的访问定位

    一 Java对象的内存布局 在HotSpot虚拟机中,对象在内存中的布局分为3个区域 对象头(Header) Mark Word(在32bit和64bit虚拟机上长度分别为32bit和64bit)存储 ...

  6. 3 Java对象的内存布局以及对象的访问定位

    先来看看Java对象在内存中的布局   一 Java对象的内存布局 在HotSpot虚拟机中,对象在内存中的布局分为3个区域 对象头(Header) Mark Word(在32bit和64bit虚拟机 ...

  7. Java对象的内存模型(一)

    前言 新人一枚,刚刚入门编程不久,各方面都在学习当中,博文有什么错误的地方,希望我们可以多多交流! 最近,在开发App后台过程中,需要将项目部署到云服务器上.而云服务器的内存大小却只有1G.要如何做到 ...

  8. Java对象的内存布局

    对象的内存布局 平时用java编写程序,你了解java对象的内存布局么? 在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域: 对象头 实例数据 对齐填充 对象头 对象头包括两部分信息: ...

  9. java对象在内存的大小

    前言 一直以来,对java对象大小的概念停留在基础数据类型,比如byte占1字节,int占4字节,long占8字节等,但是一个对象包含的内存空间肯定不只有这些. 假设有类A和B,当new A()或者n ...

随机推荐

  1. comm命令——

    comm命令 :对已经有序的文件进行比较——第一列只在文件1中出现的文件,第二列只在文件2中出现的文件,第三列在文件1和文件2中同事出现的文件 请注意前提条件:             comm对文件 ...

  2. 在ubuntu系统荣品开发配套JDK安装

    chmod 755 jdk-6u29-linux-i586.bin ./jdk-6u29-linux-i586.bin

  3. MFC框架

    第一点:类别型录网的搭建: 类别型录网搭建的目的是为了实现所谓的"执行期类型识别",也就是在程序运行的时候识别出某个对象是否是某个类的实例(基类也可以).这里还不是很明白为什么需要 ...

  4. [swustoj 191] 迷宫逃离

    迷宫逃离(0191) 描述 江鸟突然想到了一个迷宫逃离的游戏,话说有三个人被困于一个n*m的迷宫里,他们三人都可以向上.向下.向左.向右四个方向进行走动,当然他们所在的初始位置没有障碍物,同时只能走到 ...

  5. 全新 D 系列虚拟机型号

    Kenaz KwaAzure计算运行时项目经理 今天,我们宣布将发布名为D系列的Windows Azure 新VM型号,并支持虚拟机和 Web/Worker Role.这些虚拟机型号最多可以提供 11 ...

  6. 在Eclipse中使用Github(EGit)

    安装配置EGit 1. 安装Windows版的Git,登陆Github账号,登陆成功后会自动在本地和Github配置好密钥 2. 在Eclipse中安装EGit,地址http://download.e ...

  7. Android中界面实现全屏显示的两种方式

    在开发android的应用当中,我们会遇到将一些界面设置为全屏显示的格式,有两种实现的方法.其一是在Java代码中实现,其二是在配置文件中实现. 1. 在Java代码中设置 super.onCreat ...

  8. Spring读取加密属性文件处理

    引言:Spring框架俨然已经是目前Java WEB项目开发的一个宠儿,更有人将Spring, Struts,和Hibernage称之为Java WEB项目开发的3件利器.Spring的依赖.注入.A ...

  9. Using the Task Parallel Library (TPL) for Events

    Using the Task Parallel Library (TPL) for Events The parallel tasks library was introduced with the ...

  10. HDU 1881

    思路:一开始以为rating相同的点就直接比较rp然后建图,后来想想不对,因为这样发现不了冲突.后来一想对于rating相同的点可以不用排序,因为对于这些点,他们的rp必然不相同,也就是说在这些点的内 ...