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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 在官网下载最新版Java

    在官网下载最新版Java在Oracle官网下载最新版Java1.进入oracle官网https://www.oracle.com2.点击下拉菜单中的java3.点击如图所示4.点击最新版的javase5.若要下载其他版本,则拉滚动条至最下方,点击如图所示6.各个版本的JavaSE都展示出来了,如图所示,这里下载JavaSE9为例7.勾选下方的AcceptLicenseAgreement,否…

    2022年7月7日
    37
  • 【STM32】STM32CubeMX教程二–基本使用(新建工程点亮LED灯)

    【STM32】STM32CubeMX教程二–基本使用(新建工程点亮LED灯)前言在配置好CubeMX之后,就是新建工程的开始了,那么首先我们需要一些准备,本片博客我们会很详细的介绍STM32CubeMx的基本使用和如何创建一个新的工程并且点亮LED灯面向初学者如果您想着快速实现工程的创建,可以直接跳过功能介绍,观看工程创建一栏并且,在新建工程时,我们分为了具体流程1~7如果您不想看每部分的讲解,直接按照流程操作即可,5分钟即可成功点亮LED灯安装…

    2022年6月14日
    46
  • IsoAlgo3d – A PCF 3D Viewer for Desktop, Tablet and Smart phone

    IsoAlgo3d – A PCF 3D Viewer for Desktop, Tablet and Smart phone

    2022年3月8日
    41
  • 前端零基础教学开始第六天 06 – day 多种定位方法 和 精灵图使用 元素的显示与隐藏…[通俗易懂]

    前端零基础教学开始第六天 06 – day 多种定位方法 和 精灵图使用 元素的显示与隐藏…[通俗易懂]1、定位与浮动的区别:浮动只能浮动到左面与右面2、定位想定在页面上想定到哪里可以定到任意位置。定位一共有四种position:固定定位: fixed绝对定位:absolute相对定位:relative静态定位:static固定定位##固定定位<!DOCTYPEhtml><head> <metacharset=”UTF-8″&gt…

    2022年5月29日
    40
  • jdbc是数据库连接池么_零之轨迹超详细攻略

    jdbc是数据库连接池么_零之轨迹超详细攻略JDBC数据库连接池一、JDBC数据库连接池的必要性二、数据库连接池技术三、多种开源的数据库连接池3.1C3P0数据库连接池3.2DBCP数据库连接池3.3Druid(德鲁伊)数据库连接池一、JDBC数据库连接池的必要性1、在使用开发基于数据库的web程序时,传统的模式基本是按以下步骤:(1)在主程序(如servlet、beans)中建立数据库连接(2)进行sql操作(3)断开数据库连接2、这种模式开发,存在的问题:(1)普通的JDBC数据库连接使用DriverManager来

    2022年9月17日
    0
  • NGUI中穿插粒子或者mesh渲染层级

    NGUI中穿插粒子或者mesh渲染层级

    2022年2月22日
    34

发表回复

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

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