java的局部变量和全局变量_java全局变量和局部变量

java的局部变量和全局变量_java全局变量和局部变量我们先来看一个比较的例子,最近在知乎看到的帖子。publicclassTestDemo{inta;//类的成员变量publicstaticvoidmain(String[]args){TestDemotd=newTestDemo();//默认的构造方法System.out.println(td.a);…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

变量的初始化问题

我们先来看一个例子,最近在知乎看到的帖子。

 
  public class TestDemo { 
   
    int a;  //类的成员变量
    public static void main(String[] args) { 
   
        TestDemo td =new TestDemo(); //默认的构造方法
        System.out.println(td.a);
    }
}

    // 第二种类型 
  public  class TestDemo { 
   
    public static void main(String[] args) { 
   
       int a;
       System.out.println(a);
    }
}

  我先验证了一下结果给大家说,上面部分代码运行结果为 0 . 下面部分代码编译执行报错(变量可能未初始化)。

成员变量和局部变量的区别

  上面两部分代码的区别是上面代码,变量 a 是作为类的成员变量,主方法中创建了对象,我们发现此时的 a 结果是 0,如果我们换成字符串就是 null ,boolean型变量默认就是 false ,所以我们发现当变量作为类的成员变量的时候类在创建对象的时候会默认给它们赋初值。

  而下面部分代码则是方法中的变量,也就是局部变量。我们直接打印它或者用到它的时候直接会报错。

  如何解释这一现象?局部变量必须赋初始值?下面我们多方面分析一下。

  首先,Java语言是这么明文规定的。局部变量使用前必须赋值。为什么Java 语言要这么规定呢。我们知道Java 是一门面向对象的语言,它将重点放在 数据 和对象的接口上。就好比一个木匠,一个“面向对象”的木匠始终关注的是所制作的椅子,第二位才是所使用的工具和打造的过程;而一个“非面向对象的”木匠首先考虑的是所用的工具。

  最上面部分代码,将 a 变量作为类的成员变量,当我们创建对象的时候,Java 虚拟机会在系统的堆 (heap)区域申请一块内存区域来存放类的数据,在这里成员变量就是类的数据,这个时候JVM为加载的类要分配内存啦!成员变量作为类的数据是会随着类的加载在堆中分配内存,注意了,JVM 在申请内存时自动给它们赋了初值。这里附上下面一个堆栈简单示意图,
在这里插入图片描述

  至于默认给类的成员变量赋初值有什么机理吗?我们可以想到类都有一个默认的构造方法的。(因为我们没有给出显式的构造方法)我们创建对象的时候实际上是调用了默认的构造方法的,会给成员变量赋一个默认的初始值,这样在打印输出的时候才会有值输出而不报错。这时我们看一下第二段代码,并没有涉及到任何实例化对象的操作,在主函数里面 a 是没有任何东西对其初始化的,所以直接对其输出会直接报错。

  现在我们想一想如果Java 设计的时候也给方法里的局部变量赋初始值会怎样? 一个方法里面可能会有很多个局部变量,类里面也会有很多个方法,而且生命周期短。如果我们都给它们赋初值,一定是一笔很大的开销,而且安全性也达不到要求,所以换成我是虚拟机也不想干这等活儿…但程序员们最好有给局部变量初始化的习惯。我们不妨看下下面这个例子。

    public static void main(String[] args) { 
   
        for (int i = 0; i < 100; i++) { 
   
            int a;
            if (i % 2 == 0) { 
   
                a = 1;
            } else { 
   
                a = 2;
            }
        }
    }

如果我们每次都对 a 进行初始化,那真的是丝毫没有必要的。

  我们还可以换个角度来想这个问题,假如你是开发 Java 这门伟大语言的开发者,你在设计的时候,类的成员变量是要在堆中分配内存的,方法中的局部变量是在栈中的。其实,不管是局部变量还是成员变量,都是必须要初始化的,那为什么成员变量会自动初始化?其实正是因为成员变量属于对象,而对象是保存在堆中的,随着类的加载在为对象开辟空间的时候自动为成员变量赋初值,如果我们还要给局部变量都赋初值,那性能影响太大了吧,开发者想到这里的时候可能就直接将给局部变量初始化的想法抹杀掉了吧。同时在一般情况下成员变量也不会有初始值,你可以联想一下,有一个class 比如说是人类,里面的身高体重如果定义时候给了初始值,是不是觉得一点都不抽象了,所以成员变量不初始化可能更符合需求,创建类的对象的时候它们也会有初始值。(ps: static 修饰的成员变量不用创建对象也可以哦)

  最后套用《Thinking in Java》作者的话:

编译器当然可以为局部变量附一个默认值,但是未初始化的局部变量更有可能是程序员的疏忽,所以采用默认值范围会掩盖这种失误。因此强制程序员提供一个初始值,往往能够帮助找出程序里的缺陷。

果然是大佬,说出来的话就是让人无可反驳。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/171758.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Kong集群(hybrid混合)部署模式

    Kong集群(hybrid混合)部署模式kong集群部署与promethues指标采集

    2022年6月26日
    27
  • hadoopfs命令详解_hadoophdfs命令上传

    hadoopfs命令详解_hadoophdfs命令上传格式:hadoopfs-命令主要有如下的命令:命令说明hadoopfs-mkdir创建HDFS目录hadoopfs-ls列出HDFS目录hadoopfs-copyFromLocal使用-copyFromLocal复制本地文件(local)到HDFShadoopfs-put使用-put复制本地(local)文件到HDFShadoopfs-copyToLocal将HDFS上的文件复制到本地(local)hadoopfs-get将HDFS上的文件复制到本地

    2022年10月4日
    2
  • 字符串匹配的kmp算法_多字符串匹配

    字符串匹配的kmp算法_多字符串匹配一、背景  给定一个主串(以S代替)和模式串(以P代替),要求找出P在S中出现的位置,此即串的模式匹配问题。  Knuth-Morris-Pratt算法(简称KMP)是解决这一问题的常用算法之一,这个算法是由高德纳(DonaldErvinKnuth)和沃恩·普拉特在1974年构思,同年詹姆斯·H·莫里斯也独立地设计出该算法,最终三人于1977年联合发表。  在继…

    2022年8月21日
    8
  • 命令行修改hosts_windows host文件

    命令行修改hosts_windows host文件命令行修改host文件打开终端;sudovi/etc/hosts;提示输入电脑密码输入密码,点击enter键,进入host页面;点击键盘i,命令行最下方显示–INSERT–,意思是当前可以编辑,输入需要修改的host;点击esc退出编辑;同时按住shift和:,输入wq保存退出host页面;…

    2022年10月11日
    2
  • 海量数据处理分析

    海量数据处理分析 笔者在实际工作中,有幸接触到海量的数据处理问题,对其进行处理是一项艰巨而复杂的任务。原因有以下几个方面:一、数据量过大,数据中什么情况都可能存在。如果说有10条数据,那么大不了每条去逐一检查,人为处理,如果有上百条数据,也可以考虑,如果数据上到千万级别,甚至过亿,那不是手工能解决的了,必须通过工具或者程序进行处理,尤其海量的数据中,什么情况都可能存在,例如,数据中某处格式出了问题

    2022年6月23日
    35
  • Java学习之Spring框架基础篇

    Java学习之Spring框架基础篇0x00前言续上篇文章,继续更新Spring框架内容。0x01Bean自动装载注解自动装载在spring框架里面可以自动装配Bean。我们只需要在b

    2021年12月12日
    110

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号