局部变量与全局变量
局部变量与全局变量
- 变量的作用域
- 基本数据类型变量与引用数据类型变量
变量的作用域
Java中变量的作用域可以分为四个级别:类级(类变量),对象实例级(实例变量),方法级(局部变量),块级(局部变量)
类型 | 从属于 | 声明位置 | 作用域 | 初始化 |
---|---|---|---|---|
类变量(静态变量) | 类 | 类内部,方法外,static修饰 | 与类同在,类被加载静态变量就有效,直至类被回收机制回收时消失 | 必须先声明、初始化,才能使用 |
成员变量(实例变量) | 对象实例 | 类内部,方法外 | 有对应的实例对象创建时创建成员变量;对象消失时,成员变量消失 | 不用自行初始化,默认初始值 |
局部变量 | 方法 / 代码块 | 方法中或代码块内 | 从声明时开始,到所在的方法或代码块执行完毕时消失 | 不用自行初始化,默认初始值 |
// 实例代码:
public class Variable {
// 静态变量 想使用这类变量,直接 类名.参数名
static String staticVariable = "我是静态变量";
// 实例变量 想使用要先创建实例对象,如果不初始化,String会默认null,int会默认0
String instanceVariable;
int age;
void Hello() {
// 局部变量 你在这个方法中声明它,那就只能在这个方法中使用它,随着方法结束,他就会消失
String name = "IT蛋";
System.out.println("Hello "+name);
System.out.println(Variable.staticVariable);
}
public static void main(String[] args) {
// 局部变量,code2尝试在代码块外定义,在代码块中赋值;code3尝试重复定义
String code2, code3;
{
code2 = "happy"; // 成功,赋值并输出
//String code3 = "happy"; 报错,已经在包含改范围的范围内定义了code3
// 局部变量 你在这个代码块中声明它,就只能在这个代码块中使用它
String code = "System.out.println('代码块内的局部变量');";
}
System.out.println(Variable.staticVariable);
System.out.println(new Variable().instanceVariable);
System.out.println(new Variable().age);
new Variable().Hello();
System.out.println(code2);
// System.out.println(name) 报错,找不到属性
// System.out.println(code) 报错,找不到属性
}
}
---输出---
我是静态变量
null
0
Hello IT蛋
我是静态变量
happy
对于局部变量,如果存在方法内部递归调用,每次在方法中的参数都是单独存在的,如下面的fun方法,方法中的mid递推了五次,因为内部递归不会影响到外部,所以我们可以看到输出的值由顺序1-5后又从5-1输出,为了区分输出语句,我在递归返回当前方法的输出中加了个 “ | “ 。
public class Variable2 {
public static void main(String[] args) {
for(int i=0; i<3; i++) {
// 局部变量 i
System.out.print(i + " ");
}
// System.out.println(i);
System.out.println();
System.out.println("------------");
int[] nums = new int[]{1,2,3,4,5};
fun(nums,0);
}
static void fun(int[] nums, int i){
int mid = nums[i];
System.out.print(mid + " ");
if(i<nums.length-1)
fun(nums,i+1);
System.out.print(mid + "| ");
return;
}
}
---输出---
0 1 2
------------
1 2 3 4 5 5| 4| 3| 2| 1|
实例题目:Day15_树的遍历_剑指Offer | IT蛋的个人博客 (xcscx.github.io)
// 部分代码:对于target(形参)作用域与方法变量(局部变量)一致
public void findWay(TreeNode root, int target) {
...
// 传入方法的target不论怎么变,当前的target都不会收到影响,好比是复制了一份丢给方法,本体不受影响
findWay(root.left, target);
findWay(root.right, target);
...
}
基本数据类型变量与引用数据类型变量
变量的属性会影响变量的传递:
- 如果参数是基本数据类型,此时实参赋给形参的是实参真实存储的数据值。
- 如果参数是引用数据类型,此时实参赋给形参的是实参存储数据的地址值。
public class Variable3 {
public static void main(String[] args) {
int[] nums = new int[]{1,2,3,4,5};
int a = 22;
System.out.println("a = " + a);
System.out.print("nums = ");
for(int num : nums) System.out.print(num+" ");
System.out.println();
System.out.println("-----");
change(nums, a);
System.out.println("a = " + a);
System.out.print("nums = ");
for(int num : nums) System.out.print(num+" ");
}
static void change(int[] nums, int a) {
nums[1] = 0;
a = 100;
}
---输出---
a = 22
nums = 1 2 3 4 5
-----
a = 22
nums = 1 0 3 4 5
上述代码中,我们发现对于int类型的a,传递值确实如一开始说的那般,不会收到方法中修改的影响,但是int[] 的值却被修改了。
这也证明了引用类型传递的是参数的地址,所以会受到方法中修改的影响
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 IT蛋的个人博客!