java类变量和实例变量详解,具体代码展示

BSO 2020-09-04 10:33:48 java常见问答 3146

java的知识群庞大而丰富,使人沉迷其中不可自拔。今天就来为大家介绍一下java类变量和实例变量的具体内容,并且通过实际的代码为大家展示。

首先,我们来看一下类变量 (静态变量)的具体内容。

类变量可以向前引用,变量属于类本身。类变量不依赖类的实例,它只在初始化的时候在栈内存中被分配一次空间。并且无论类的实例被创建几次,都不再为类变量分配空间。通过类的任意一个实例来访问类变量,底层都将使其转为通过类本身来访问类变量,而且它们的效果是一样的。假如类变量的值被改变,通过类或类的任意一个实例来访问类变量,得到的都将是被改变后的值。类变量将在类的初始化之前初始化。

接下来看一下实例变量(非静态变量)。它不能向前引用,如果向前引用,则称为非法向前引用,这是不被允许的。变量属于类的实例对象,随着类的实例被创建而分配内存空间。

再补充说明一下非静态代码块,也就是直接由{ }包起来的代码。还有静态代码块,它是直接由static{ }包起来的代码。

再来总体说一下它们的初始化时机。

1.被static关键字修饰的(如:类变量[静态变量]、静态代码块)将在类被初始化创建实例对象之前被初始化,而且是按顺序从上到下依次被执行;

2.没有static关键字修饰的(如:实例变量[非静态变量]、非静态代码块)初始化实际上是会被提取到类的构造器中被执行的,但是会比类构造器中的代码块优先执行,也是按顺序从上到下依次被执行。

接下来为大家展示具体的实例:

public class Statical
{
    /**
     * 静态代码块
     * 类变量(静态变量)可以向前引用(即:先引用,再定义)
     */
    static
    {
        name = "fancydeepin"; // name 的定义在使用之后
        System.out.println("--->  静态代码块被执行   <---");
    }
    /**
     * 类变量(静态变量)在类的初始化之前初始化,无论类的实例将被创建多少个
     * 类变量(静态变量)都将只在初始化时候在栈内存上分配一次空间
     * 凡 static 修饰的,都将按位置被顺序执行,所以,
     * name 的值最终输出 fancy 而不是上面的 fancydeepin
     */
    public static String name = "fancy"; //类变量(静态变量)
    private String mail = "myEmail"; //实例变量(非静态变量),定义时指定初始值,会比在构造器赋予值更早执行
    public Statical()
    {
        mail = "fancydeepin@yeah.net";
        System.out.println("---> 构造器代码块被执行 <---");
    }
    /**
     * 非静态代码块
     * 实际上,非静态代码块在类初始化创建实例时,将会被提取到类的构造器中,
     * 但是,非静态代码块会比构造器中的代码块优先被执行
     * 所以,mail 最终输出的是类构造器中给定的值,也就是 fancydeepin@yeah.net
     * 而不是 1525336367@qq.com,更不是 myEmail
     */
    {
        mail = "1525336367@qq.com";
        System.out.println("---> 非静态代码块被执行 <---");
    }
    // getting and setting

测试类的具体代码:

 /**
  * 类变量(静态变量)在类被初始化创建实例之前被初始化
  */
 System.out.println("-----------------> @1 <----------------");
 System.out.println("name --->> " + Statical.name); // @1
 System.out.println("-----------------> @1 <----------------");
 /**
  * 创建类的实例对象
  */
 System.out.println("-----------------> @6 <----------------");
 Statical statical = new Statical(); // @6
 System.out.println("-----------------> @6 <----------------");
 /**
  * 通过实例来访问类变量,底层将转化成通过类本身来访问类变量
  */
 System.out.println("-----------------> @2 <----------------");
 System.out.println("name --->> " + statical.name); // @2
 System.out.println("-----------------> @2 <----------------");
 /**
  * 如果类变量的值被改变,再访问类变量,将得到被改变后的值
  */
 Statical.name = "fancydeepin";
 System.out.println("-----------------> @3 <----------------");
 System.out.println("name --->> " + statical.name); // @3
 System.out.println("-----------------> @3 <----------------");
 System.out.println("-----------------> @4 <----------------");
 System.out.println("name --->> " + Statical.name); // @4
 System.out.println("-----------------> @4 <----------------");
 /**
  * 非静态代码块 和 构造器 被执行的时机
  */
 System.out.println("-----------------> @5 <----------------");
 System.out.println("mail --->> " + statical.getMail()); // @5
 System.out.println("-----------------> @5 <----------------");

后台运行结果如下:

-- -- -- -- -- -- -- -- - > @1 < -- -- -- -- -- -- -- --
    -- - > 静态代码块被执行 < -- -
    name-- - >> fancy
    -- -- -- -- -- -- -- -- - > @1 < -- -- -- -- -- -- -- --
    -- -- -- -- -- -- -- -- - > @6 < -- -- -- -- -- -- -- --
    -- - > 非静态代码块被执行 < -- -
    -- - > 构造器代码块被执行 < -- -
    -- -- -- -- -- -- -- -- - > @6 < -- -- -- -- -- -- -- --
    -- -- -- -- -- -- -- -- - > @2 < -- -- -- -- -- -- -- --
name-- - >> fancy
-- -- -- -- -- -- -- -- - > @2 < -- -- -- -- -- -- -- --
    -- -- -- -- -- -- -- -- - > @3 < -- -- -- -- -- -- -- --
name-- - >> fancydeepin
-- -- -- -- -- -- -- -- - > @3 < -- -- -- -- -- -- -- --
    -- -- -- -- -- -- -- -- - > @4 < -- -- -- -- -- -- -- --
name-- - >> fancydeepin
-- -- -- -- -- -- -- -- - > @4 < -- -- -- -- -- -- -- --
    -- -- -- -- -- -- -- -- - > @5 < -- -- -- -- -- -- -- --
mail-- - >> fancydeepin @yeah.net
    -- -- -- -- -- -- -- -- - > @5 < -- -- -- -- -- -- -- --

以上就是关于java类变量和实例变量详细解析,并且通过实际的代码为大家展示出来。想要了解更多java基础,敬请关注奇Q工具网。

推荐阅读:

java变量主要有哪几类?具体如何操作?

在java中如何用this区分成员和局部变量,图片详解

java常量与变量的区别是?