`
msn877763580
  • 浏览: 83832 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

关于java变量的几个概念

 
阅读更多

成员变量:指类范围内定义的变量。(实例属性,类属性(以static修饰))


实例属性和类属性的区别:

一个是类的方法(也叫动态属性)和属性(静态属性),通过类名来访问;
一个是对象的方法和属性,需要通过一个实例来访问。
静态属性程序一加载时 就初始化 存放在栈中;
实例属性 需要实例化后 才加载 存放在堆中。


局部变量:指的是一个方法内的变量。(形参,方法局部变量,代码块局部变量)


关于变量初始化的顺序,以及new一个对象时会不会同时产生一个父类的对象,甚至是Object对象,ITeye上收集的信息如下,个人认为比较的详细。

huoyj写道
类加载主要有三个过程:装载,链接和初始化。
装载是最好理解的,就是将编译生成的二进制文件装到内存中。
链接:这个过程又可以分为三个子过程,即校验,准备和解析,校验当然就是对已装入内存中的二进制类文件校验,检查其是否符合class文件的规范,同时它还要提取一些类的关键信息,比如变量和方法。准备就是对类变量分配存储空间,同时会初始化。解析:将符号引用转成直接引用;也就是对引用变量分配空间,并初始化。注意;在链接的时候会对变量分配空间并初始化,但这时候的初始化并不是很可靠的。
初始化:这时候会执行真正的初始化语句即执行构造方法对变量初始化。
由以上的过程可以得出在类加载的时候执行的顺序为:静态变量ok -> 静态代码块 -> 变量ok -> 普通代码块 -> 构造方法开始执行。


 

jameswxx 写道
当new一个对象的时候发生了什么?我就给大家讲讲吧,如果不对的地方,还请大家指正
如new MyObject();

1:寻找类定义
jvm会在自己的一个名叫“方法区”的内存块中,寻找名叫“MyObject”的Class对象(注意class也是一个对象,该对象记录了所有类的定义),如果有,则按照Class对象的定义,生成一个MyObject对象。

2:加载类定义
如果“方法区”中没有名为“MyObject”的Class对象,jvm会用当前类的类加载器(classloader)从当前的classpath路径寻找名为"MyObject.class"的文件,如果找到,则将文件进行分析,转换为Class对象存放在“方法区”中,否则抛出“ClassNotFoundException”。对于jdk的class,jvm启动时,会用启动类加载器加载,对于用户的class,则会用应用程序类加载器实时加载,所谓实时加载,指的是遇到的时候再加载,而不是预先一次性加载。关于类加载器,有三级,jvm严格的限制了每一级的加载权限,加载模式为“双亲委托模式”,加载任何类,都先由父加载器加载。

3:给对象分配内存空间
找到MyObject的类定义后,jvm在内存“堆”中,开辟一个空间,该空间按照MyObject类定义开辟,并将该空间中的各个内存段设置默认值,对应的就是对象的属性初始化默认值。

4:对象的初始化顺序
对象的初始化都先从父类开始,顺序如下:
给父类静态变量默认值
对父类静态变量赋值
执行父类静态块

给当前类静态变量默认值
对当前类静态变量赋值
执行当前类静态块

给父类变量默认值
对父类变量赋值
执行父类构造函数

给当前类变量默认值
对当前类变量赋值
执行当前类构造函数

5:对象构造完成

还有一点要提醒楼主,当你new一个String的时候,只是生成一个String对象,而没有生成Object对象,Object的类定义在“方法区”这块内存中,当new String的时候,jvm会检查String的父类,找出父类的定义,并找出哪些是String可以拥有的,然后按照筛选出来的父类定义和String本身的类定义,在堆中分配一个内存块(就是俗称的生成了一个对象),而没有专门为String的父类Object分配空间。

其实你可以想想下,如果像你那么说,new一个String的时候,还会生成一个Object对象,那java简直没法使用了,因为Obejct是所有对象的父类,使用任何对象都会生成一个Object对象,还不算其他的父类。如果这样,多大的内存也不够用,即使内存够了,CPU也会忙死,因为这么多对象,后台的gc执行一次收集清除,都累得够呛了。特别是现在的gc机制都是按代收集的,对象巨多,年轻代很容易满,导致gc收集启动,应用程序会停顿。这样的系统谁能用呢?

 对于jameswxx中所说的对象的初始化顺序不能完全赞同,下面引用臧圩人·海纳百川的文章说明。

臧圩人·海纳百川 写道
public class Parent {
// 静态变量
public static String p_StaticField = "父类--静态变量";
// 变量
public String p_Field = "父类--变量";
// 静态初始化块
static {
System.out.println(p_StaticField);
System.out.println("父类--静态初始化块");
}
// 初始化块
{
System.out.println(p_Field);
System.out.println("父类--初始化块");
}
// 构造器
public Parent() {
System.out.println("父类--构造器");
}
}

public class SubClass extends Parent{
// 静态变量
public static String s_StaticField = "子类--静态变量";
// 变量
public String s_Field = "子类--变量";
// 静态初始化块
static {
System.out.println(s_StaticField);
System.out.println("子类--静态初始化块");
}
// 初始化块
{
System.out.println(s_Field);
System.out.println("子类--初始化块");
}
// 构造器
public SubClass() {
System.out.println("子类--构造器");
}
// 程序入口
public static void main(String[] args) {
new SubClass();
}
}

执行结果:
父类--静态变量
父类--静态初始化块
子类--静态变量
子类--静态初始化块
父类--变量
父类--初始化块
父类--构造器
子类--变量
子类--初始化块
子类--构造器


臧圩人·海纳百川 写道
现在,结果已经不言自明了。大家可能会注意到一点,那就是,并不是父类完全初始化完毕后才进行子类的初始化,实际上子类的静态变量和静态初始化块的初始化是在父类的变量、初始化块和构造器初始化之前就完成了。

那么对于静态变量和静态初始化块之间、变量和初始化块之间的先后顺序又是怎样呢?是否静态变量总是先于静态初始化块,变量总是先于初始化块就被初始化了呢?实际上这取决于它们在类中出现的先后顺序。
静态变量和静态初始化块是依照他们在类中的定义顺序进行初始化的。同样,变量和初始化块也遵循这个规律。


 

分享到:
评论

相关推荐

    java变量命名心得

    下面我们将通过一个实例来展示局部变量和实例变量的区别,并总结 java 变量命名的几个典型问题。 首先,让我们来看一下局部变量和实例变量的区别。局部变量是指在方法内部定义的变量,它的作用域仅限于该方法内部。...

    Java变量笔记

    根据提供的信息,我们可以总结出以下关于“Java变量”的知识点: ### Java 变量基础 #### 1. 变量的概念 在 Java 中,变量是用来存储数据的标识符。每个变量都具有一个特定的数据类型,这决定了它能存储的数据种类...

    java环境变量设置

    Java 环境变量设置是 Java 开发和运行的基础,它包括安装 JDK 和 JRE、配置环境变量、编译和运行 Java 程序等几个方面。下面是 Java 环境变量设置的详细知识点: 一、安装 JDK 和 JRE 在 Windows Server 2003...

    java变量讲解

    在 Java 语言中,每一个变量都需要先声明再使用。 #### 二、变量的定义格式 定义一个变量的基本格式为:`数据类型 变量名 = 初始化值;` 例如: ```java int age = 32; // 定义了一个整型变量age,并初始化为32 ```...

    java,环境变量,Java环境变量配置

    这些变量主要包含`JAVA_HOME`、`CLASSPATH`以及`path`(或`Path`)等几个重要的部分。 - **`JAVA_HOME`**:用来指定JDK的安装目录,它是其他环境变量的基础。 - **`CLASSPATH`**:用来指定Java虚拟机(JVM)查找用户...

    Java中的常量和变量概念及定义.docx

    ### Java中的常量和变量概念及定义 #### 一、常量 在Java程序中,常量是指在程序执行过程中其值不会发生改变的量。理解常量的概念对于编程...这两个概念是Java编程的基础,对于理解和编写高质量的Java程序至关重要。

    Java编程变量的概念及命名[定义].pdf

    在Java中,变量有以下几个关键点: 1. **变量定义**:变量是用来存储数据的内存单元。当我们定义一个变量,实际上是告诉编译器变量的数据类型,例如`int age`表示年龄是一个整数类型。这有助于编译器为变量分配适当...

    浅谈java中的四个核心概念

    Java API分为以下几个部分: 1. **标准API**:这是Java最基础的部分,包括了核心类库,如`java.lang`、`java.util`等。 2. **扩展API**:这部分API通常包含在扩展包中,例如`javax.*`包,它们提供了更多的高级功能...

    Java引用变量传递诡异之处

    本文将通过两个具体的例子来探讨Java中引用变量传递时的一些常见误区,并对这些误区进行详细的解释。 #### 示例一:基本类型包装类的传递 首先,我们来看第一个例子: ```java public class Test1 { public ...

    为什么 Java 需要设置环境变量

    本文将详细探讨 Java 中常用的几个环境变量(如 PATH、CLASSPATH 和 JAVA_HOME)的重要性及其具体作用,帮助读者更好地理解为什么 Java 需要设置这些环境变量。 #### 1. PATH 环境变量 PATH 环境变量对于任何操作...

    java环境变量设置工具

    通常,Java环境变量包括以下几个关键部分: 1. **JAVA_HOME**:这个变量指向Java安装的根目录。它的设置使得其他依赖于Java的程序能够找到Java的安装位置,例如Java编译器(javac)、Java解释器(java)以及其他的...

    java环境变量.txt

    本文将从给定的文件信息出发,详细阐述与Java环境变量相关的几个关键概念及其设置方法。 #### 1. Java环境变量概述 环境变量是操作系统提供的一种机制,用于存储对系统运行有影响的信息。对于Java开发者而言,正确...

    java 环境变量设置大全

    在安装JDK后,我们需要配置几个关键的系统环境变量。 1. **JAVA_HOME**:这个环境变量指向JDK的安装目录。例如,在Windows上,如果你的JDK安装在`C:\Program Files\Java\jdk1.8.0_231`,则应设置JAVA_HOME为这个...

    轻松学会java环境变量设置

    Java环境变量主要包括以下几个方面: 1. **JAVA_HOME**:该变量指向Java Development Kit (JDK) 的安装路径。 2. **CLASSPATH**:用于指定Java类(.class文件)和库文件的搜索路径。 3. **Path**:定义了系统查找可...

    Java中变量.pdf

    Java是一种广泛使用的面向对象的编程语言,其语法严谨且具有丰富的特性。在Java中,变量是程序中的基本存储单元,用于存储不同类型的数据。...因此,深入理解这些概念对于成为一个合格的Java程序员来说是必不可少的。

    java环境变量设置.txt

    对于Java而言,主要涉及以下几种环境变量的设置: - **JAVA_HOME**:指向Java开发工具包(JDK)的安装目录。 - **PATH**:包含JDK的bin目录路径,以便在命令行中可以不带路径直接执行`java`、`javac`等命令。 - **...

    java 利用反射获取内部类静态成员变量的值操作.docx

    在深入探讨之前,我们需要了解几个基本概念: 1. **内部类**:内部类是一种特殊的类,定义在另一个类(外部类)的内部。它可以访问外部类的所有成员(包括私有成员),同时也可以被外部类所访问。 2. **静态成员变量...

    关于Java变量的声明、内存分配及初始化详解

    本文将深入探讨Java变量的声明、内存分配以及初始化。 首先,变量的声明是指在程序中定义一个变量,指定其类型和名称。例如,`String name;` 和 `int age;` 在`Person`类中声明了两个变量,`name`是一个字符串类型...

Global site tag (gtag.js) - Google Analytics