首页 > 编程语言 >Java——变量作用域和生命周期

Java——变量作用域和生命周期

时间:2024-06-15 17:00:53浏览次数:23  
标签:生命周期 Java 变量 作用域 局部变量 int 全局变量 public

一、作用域

1、作用域简介

在Java中,作用域(Scope)指的是变量、方法和类在代码中的可见性和生命周期。理解作用域有助于编写更清晰、更高效的代码。

2、作用域

块作用域(Block Scope):

块作用域是指在大括号 {} 内定义的变量的作用域。变量只在其定义的块内可见和有效,包括循环、条件语句和代码块。

方法作用域(Method Scope):

方法作用域指的是在方法内定义的变量的作用域。变量在整个方法内可见和有效。

类作用域(Class Scope):

类作用域指的是在类中定义的成员变量的作用域。成员变量在整个类内可见和有效。

二、全局变量和局部变量

1、全局变量

全局变量在Java中通常指的是类级别变量,或者说是类的属性。包括实例变量和静态变量。这些变量的作用域在整个类内,它们可以在类的所有方法中访问和修改。

1)实例全局变量

实例变量是类的非静态成员变量。它们属于类的每个实例,每个实例都有自己的一份实例变量。对于类的实例变量也是全局变量,在这个类的每一个方法中都能访问:

class Person {
	//全局变量,类的属性
	String name;
	int age;

	//构造方法
	public Person(String name, int age) {
		this.name = name;//在每个方法中都能访问到这个全局变量
		this.age = age;//在每个方法中都能访问到这个全局变量
	}
	//获取年龄
	public int getAge() {
		return age;//在每个方法中都能访问到这个全局变量
	}
	//设置年龄
	public void setAge(int age) {
		this.age = age;//在每个方法中都能访问到这个全局变量
	}
	//获取名字
	public String getName() {
		return name;//在每个方法中都能访问到这个全局变量
	}
	//设置名字
	public void setName(String name) {
		this.name = name;//在每个方法中都能访问到这个全局变量
	}
}

可以看到这里的属性或者说是全局变量在这个类的每一个方法中都能访问到。

2)静态全局变量

静态变量是使用static关键字声明的类变量。它们属于整个类,而不是任何特定实例。所有实例共享同一个静态变量。类的静态变量在这个类的每一个方法中都能访问:

public class MyClass {
    // 静态变量
    private static int staticVariable = 0;

    public MyClass() {
        staticVariable++;
    }

    public void printStaticVariable() {
        System.out.println(staticVariable);
    }
}

public class Main {
    public static void main(String[] args) {
        MyClass obj1 = new MyClass();
        MyClass obj2 = new MyClass();

        obj1.printStaticVariable(); // 输出:2
        obj2.printStaticVariable(); // 输出:2
    }
}

2、局部变量

局部变量是在方法、构造函数或块中声明的变量。它们的作用域仅限于声明它们的方法、构造函数或块内,方法或块的执行结束后,局部变量将被销毁。

public class MyClass {
    public void myMethod() {
        // 局部变量
        int localVar = 100;
        System.out.println(localVar);
    }
}

public class Main {
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        obj.myMethod(); // 输出:100

        // System.out.println(localVar); // 错误,localVar在myMethod方法完成调用后就会被销毁
    }
}

这里就体现了对于定义在某个方法内的局部变量在方法调用结束后,就会被销毁。

class Cat {
	int age;

	//猫叫方法
	public void mewing() {
		String mew = "Mewing~";//这个mew就是局部变量,在mewing方法中定义,只能在mewing方法中使用
		System.out.println(mew);
	}

	//吃东西方法
	public void eat() {
		//System.out.println(mew);//在这里使用mewing方法中的局部变量mew是错误的
		//对于mew这个局部变量只能在mewing这个方法中使用
		
		//...
	}
}

这段代码体现了,定义在某个方法中的局部变量,只能在这个方法中使用,不能在其他方法中使用。

三、补充细节

1、全局变量和局部变量的赋值

全局变量可以不赋值,直接使用,因为它们有默认赋值,但是对于局部变量不赋值(不初始化)是不能使用的。

未初始化的全局变量:

public class Test {
	public static void main(String[] args) {
		Example example = new Example();
		example.foo();
	}
}

class Example {
	int a;//未赋值(未初始化)的全局变量,会被默认初始化为这个类型的默认值

	public void foo() {
		System.out.println(a);//使用这个未初始化的全局变量,它的值是默认值
	}
}

运行结果:

未初始化的局部变量:

public class Test {
	public static void main(String[] args) {
		Example example = new Example();
		example.foo();
	}
}

class Example {
	public void foo() {
		int a;//未赋值(未初始化)的局部变量
		System.out.println(a);//使用这个未初始化的局部变量,会报错
	}
}

运行结果:

2、全局变量和局部变量可以重名

在Java中,全局变量(类级别变量,包括实例变量和静态变量)和局部变量(方法、构造函数或块内声明的变量)是可以重名的,在访问时,遵循就近原则。尽管如此,这样做可能会导致代码混淆和难以维护,因此通常建议避免这种做法。

例如:

public class Test {
	public static void main(String[] args) {
		Example example = new Example();
		example.foo();
	}
}

class Example {
	int a = 6;
	public void foo() {
		int a = 16;
		System.out.println(a);//就近原则,会使用foo方法内的变量a
	}
}

运行结果:

可以发现全局变量和局部变量是可以重名的,在使用时遵循就近原则。

3、同一个作用域内不能重名

在同一个作用域中不能重名,例如在同一个方法中不能定义同名的变量,即使是不同类型同名也不行。

    public void foo() {
		int a = 16;
		double a = 0.0;
	}

这里就会报错:

4、局部变量只能用final修饰符

对于全局变量可以使用所有修饰符,但是对于局部变量就只能使用final这个修饰符,其他的都能用。

全局变量修饰符使用情况:

全局变量包括实例变量和静态变量,它们可以使用各种修饰符来指定访问权限、状态和其他特性。常用的修饰符有:

  • 访问修饰符

    • public: 变量可以被所有类访问。
    • protected: 变量可以被同一包中的类和子类访问。
    • private: 变量只能被声明它的类访问。
    • 默认(无修饰符): 变量只能被同一包中的类访问。
  • 状态修饰符

    • static: 将变量定义为类变量,共享给所有实例。
    • final: 将变量定义为常量,初始化后不能修改。
    • transient: 序列化时忽略该变量。
    • volatile: 提示线程对该变量的修改操作是可见的,多线程环境中保证变量的可见性。

局部变量修饰符修饰符使用情况:

局部变量包括方法内部、构造函数内部或代码块内部定义的变量。局部变量的作用范围仅在其声明的块内。局部变量只能使用final修饰符。

class Example {

	public void foo() {
		final int num = 0;//使用final修饰符修饰,表示这个局部变量的值不能再被改变
	}
}

与全局变量不同,局部变量不能使用访问控制修饰符(如 publicprotectedprivate)和一些状态修饰符(如 statictransientvolatile)。

class Example {
	
	public void foo() {
		public int a = 0;
		private int b = 0;
		protected int c = 0;
		static int d = 0;
		transient int e = 0;
		volatile int f = 0;
	}
}

这里就会报错:

四、变量的生命周期

在Java中,变量的生命周期决定了变量存在的时间范围。根据变量的类型和定义位置,可以将Java中的变量分为以下几类:局部变量全局变量(包括实例变量静态变量)。下面详细介绍每种变量的生命周期及特点。

1、局部变量生命周期

当局部变量所在的方法被调用时,局部变量的生命周期从它们声明开始,到包含它们的块(方法、构造函数、代码块等)结束。当方法、构造函数或代码块执行完毕后,局部变量将不再存在,内存也将被释放。

局部变量存储在栈区中。

2、全局变量生命周期

1)实例变量生命周期

实例变量的生命周期从创建对象(调用构造函数)开始,到这个对象被垃圾回收器回收时结束。实例变量在对象存在期间都可以访问。

实例变量存储在堆区中。

2)静态变量生命周期

静态变量的生命周期从类加载时开始,到类卸载时结束。静态变量在整个程序运行期间都存在,直到JVM结束。

静态变量存储在方法区(Method Area)中。

标签:生命周期,Java,变量,作用域,局部变量,int,全局变量,public
From: https://blog.csdn.net/stewie6/article/details/139702891

相关文章

  • java1
    在继承中,创建子类对象,访问成员方法的规则: 创建的对象是谁,就优先用谁,没有再向上找 注意:无论是成员变量还是成员方法, 如果没有都是向上找父类,不会向下找子类继承的特点:子类可以拥有父类的内容,此处子类还可以拥有自己独有的内容(成员变量和方法) 定义继承的格式:(至少需要......
  • 第六站:Java橙——JavaFX的动感舞台
    JavaFX入门案例:创建一个基础UI应用JavaFX允许开发者使用Java语言来设计和实现富客户端应用程序,这些应用程序具有高度互动的用户界面(UI),支持2D和3D图形,以及媒体播放等特性。下面,我们将通过一个简单的案例来展示如何使用JavaFX创建一个基本的UI应用,包括UI设计、构建场景图、......
  • 认识 Java 里的线程和方法
    Thread和Runnable的区别Thread才是Java里对线程的唯一抽象,Runnable只是对任务(业务逻辑)的抽象。Thread可以接受任意一个Runnable的实例并执行启动线程的方式有:1、XextendsThread;,然后X.start2、XimplementsRunnable;然后交给Thread运行永远都只有thread.star......
  • Linux下Java环境安装
    Linux下open-jdk1.8安装教程一.下载安装包Javadownload下载后上传到服务器二.安装1.解压安装包tar-zxvfjdk-8u341-linux-x64.tar.gz2.配置环境变量在/etc/profile文件中,新增Java的环境变量vi/etc/profileexportJAVA_HOME=/usr/local/jdk/jdk1.8.0_341export......
  • Java接口的介绍与使用,多态的介绍与使用
    第一章.接口1.接口的介绍2.接口的定义以及使用1.接口:是一个引用数据类型,是一种标准,规则2.关键字:a.interface接口publicinterface接口名{}b.implements实现实现类implements接口名{}3.接口中可以定义的成员:a.jdk7以及之......
  • Java习题
    1.题目使用Java的输入、输出流将一个文本文件的内容按行读出,每读出一行就顺序添加行号,并写入到另一个文件中。代码及详细注释importjava.io.*;//导入JavaI/O库中的所有类publicclassE{//定义一个公共类Epublicstaticvoidmain(Stringargs[]){//主......
  • Java Mail报错:javax 迁移到 jakarta
    javax(JavaExtension)作为包名,包含了一系列的Java扩展包,提供了各种不同的功能,例如servlet、JDBC、JMS等。2017年,Oracle将JavaEE技术移交给EclipseFoundation,这个项目随后被重命名为JakartaEE。在这个过渡过程中,EclipseFoundation决定将所有JavaEEAPI从java......
  • Java并发中线程池的面试题集
    写在开头之前给一个大四正在找工作的学妹发了自己总结的关于Java并发中线程池的面试题集,总共18题,将之取名为《Java并发编程之线程池十八问》,今天聊天时受了学妹的夸赞,心里很开心,毕竟自己整理的东西对别人起到了一点帮助,记录一下!Java并发编程之线程池十八问经过之前的学习,......
  • 基于Java+SpringBoot+Vue前后端分离宠物管理系统(源码+万字LW+PPT+部署教程)
    博主介绍:✌全网粉丝10W+csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌一、作品包含源码+数据库+设计文档LW+PPT+全套环境和工具资源+部署教程二、项目......
  • JVM之编写高效优雅 Java 程序
    面向对象01、构造器参数太多怎么办?如果参数很多,会导致构造方法非常多,拓展性差,代码难编写,且难以看懂。用JavaBeans模式,get和set一行构造编程多行代码实现,需要使用额外机制确保一致性和线程安全。用builder模式,1、5个或者5个以上的成员变量2、参数不多,但是在未来,......