Java的变量类型及其初始化与赋值
Java的变量类型
Java语言支持的变量类型有有局部变量和成员变量,其中成员变量包括类变量和实例变量。三种变量的特点如下:
- 类变量:独立于方法之外的变量,用 static 修饰作用范围为类中,在类中被初始化或在创建对象时初始化。
- 实例变量:独立于方法之外的变量,没有 static 修饰,作用范围为类实例化后的对象中,在类中被初始化或在创建对象时被初始化。
- 局部变量:类的方法中的变量,作用范围为方法体中,再方法体内被初始化。
注意:变量类型和变量的数据类型是不相同的。变量的作用是申请内存来存储值。也就是说,当创建变量的时候,需要在内存中申请空间。内存管理系统根据变量的数据类型为变量分配存储空间,分配的空间只能用来储存该类型数据。
其中,局部变量的初始化方法和其他高级程序语言中函数体内局部变量的初始化方法相似,在这里不做过多描述。接下来主要介绍成员变量的初始化。
类变量的初始化
类变量也叫静态变量,也就是在变量前加了static 的变量。:类变量是所有对象共有,其中一个对象将它值改变,其他对象得到的就是改变后的结果。
类变量可以在类中声明变量时初始化,也可以在创建对象时初始化。
每次创建新对象,若对类变量进行赋值,则其值更新。
- 当在类中没有对类变量进行初始化时,类变量的值为默认值。数值类型默认值为0;Boolean型默认值为false;字符串类型默认值为null。
- 在实例化对象时对类变量进行修改,则再new其他对象时类变量的值为之前修改过的值,若new对象时再给类变量赋新值,则类变量的值继续更新。
class Person{
static String age = "15"; //--类变量,在类中声明变量时初始化
public String name="李四"; //--实例变量
public static void main(String[] args){
Person A=new Person();
System.out.println(A.age); //-结果为"15"
System.out.println(A.name); //-结果为"李四"
Person B=new Person();
B.age="10";
B.name="张三";
System.out.println(B.age); //-结果为"10"
System.out.println(B.name); //-结果为"张三"
Person C=new Person();
//类变量是针对所有对象的,所以A改变age,B的age也改变
System.out.println(C.age); //-结果为"10"
//实例只改变自身的,所以A对象的name改变,不影响对象B的name变量
System.out.println(C.name); //-结果仍为"李四"
}
}
输出结果如下:
15
李四
10
张三
10
李四
实例变量的初始化
通过构造函数初始化
构造函数初始化示例
- 通过构造函数进行对象初始化,必须在类中声明一个带参数的构造函数。从而通过类创建实例的同时对实例变量进行初始化。
- 如果没有声明带参数的构造函数,调用默认构造函数,默认构造函数也对实例变量进行了默认初始化。
class Product {
private int id;
private String name;
public Product() {
}
public Product(int id, String name) {
this.id = id;
this.name = name;
}
public String toString()
{
return id+","+name;
}
public void print()
{
System.out.println(toString());
}
public static void main(String[]args)
{
Product c=new Product();
c.print();
//结果是0,null
Product s=new Product(10,"apple");
s.print();
//结果是10,apple
}
}
输出结果:
0,null
10,apple
构造函数初始化注意事项
- 如果构造函数的参数列表的参数名与实例变量的参数名一样时,需要利用this来进行指代实例变量,若不用this进行指代,则构造方法中传入的参数会被视为该方法中的局部变量,无法实现实例变量的初始化。
- 如果希望将构造函数的参数的值传递给实例变量需要用赋值语句进行传递。
以下是针对上述问题示例
构造函数带参,在构造函数中给实例变量的同名变量赋值,作用域仅在函数体内部
class Product2 {
private int id;
private String name;
private String location;
public Product2(int id, String name) {
if (id == 10)
{
id = 5;
name = "banana";
location = "China";
System.out.println("构造函数内部id:"+id);
System.out.println("构造函数内部name:"+name);
System.out.println("构造函数内部location:"+location);
}
}
public String toString()
{
return "main函数中:"+id+","+name+","+location;
}
public void print()
{
System.out.println(toString());
}
public static void main(String[]args)
{
Product2 s=new Product2(10,"apple");
s.print();
}
}
输出结果为:
构造函数内部id:5
构造函数内部name:banana
构造函数内部location:China
main函数中:0,null,China
结果解释:
- 构造函数内部的id和name:因为构造函数从主函数中传入了id和name两个参数,参数名和实例变量相同,所以在构造函数内部对这些变量进行操作时,因为局部变量的优先级更高,所以这些变量被当作局部变量进行处理,其值为主函数中传入的值。IDE会提示“id”和“name” redundant。
- 构造函数内部的location:因为构造函数传入的参数中没有"location",所以location仍为实例变量,所以此时给location赋值相当于对location进行了初始化。
- main函数中的id,name和location:因为构造函数中的id和name为局部变量,所以在主函数中,作为实例变量的id和name仍没有被赋值,其值仍为系统初始化的值;而location在类中被赋值为"China",所以其值发生变化。
注:若变量名不同,则不会将实例变量的属性更换为局部变量。
通过声明实例字段进行初始化方法
通过实例变量声明实例变量就是在创建类的时候,对实例变量进行初始化。
class SomeClass
{
static boolean b;
static byte by;
static char c;
static double d;
static float f;
static int i;
static long l;
static short s;
static String st;
}
其初始化结果为
false
0
\u0000
0.0
0.0
0
0
0
null
通过对象代码块进行初始化方法
对象代码块初始化是在类中声明代码块来进行声明实例变量。对象代码块的执行是在对象执行构造函数前执行。对象代码块前没有static关键字,加static关键字就变为类代码块。
class Product3 {
private static int price;
private int id;
private String name;
public Product3() {
}
static
{
price=100;
System.out.println("the price is:"+price);
}
public Product3(int id, String name, int price) {
this.id = id;
this.name = name;
this.price=price;
}
public String toString()
{
return id+","+name+","+price;
}
{
name="Sharplee";
}
public void print()
{
System.out.println(toString());
}
{
System.out.println("id is "+id);
System.out.println("name is "+name);
System.out.println(price);
}
public static void main(String[]args)
{
Product3 c=new Product3();
c.print();
Product3 s=new Product3(10,"apple",300);
s.print();
}
}
运行结果为
the price is:100
id is 0
name is Sharplee
100
0,Sharplee,100
id is 0
name is Sharplee
100
10,apple,300
注意点
- 类代码块无论创建多少个对象都只初始化一次,而对象代码块在创建的对象的时候都执行。
- 类代码块初始化必须在前面加关键字static,而对象代码块则不用加。
- 类代码块只能使用类变量进行初始化以及在代码块中声明变量,而对象代码块则没有限制。
- 执行顺序:类代码块初始化(只执行一次)→对象代码块初始化→构造函数初始化