1. 变量定义及其存储和访问 1. 变量类
Java中根据变量定义位置的不同,有两种类型的变量:成员变量和局部变量,而成员变量根据是否修饰又可以分为类变量和实例变量。
2. 各变量的定义
(1)成员变量:类中定义的变量(方法除外)用于描述对象的属性特征。
(2)局部变量:在类的方法中定义的变量,用于保存临时数据。
(3)类变量:成员变量中,被修饰符修饰的变量称为类变量,也称为静态变量
(4)实例变量:成员变量中,未被修饰符修饰的变量称为实例变量
3.每个变量区分类变量、实例变量、局部变量
定义位置
类内、方法外
类内、方法外
方法,或者方法形式的参数
初始化值
有一个默认的初始化值
有一个默认的初始化值
没有定义,赋值后即可使用
调用方法
对象调用,类名直接调用
对象调用
存储位置
方法区
在堆里
在堆栈中
生命周期
与班级同生共死
与物体同生同死
生死皆有方法
别名
静态变量
解释:
4. 各变量注意事项
类名.类变量名
实例名.类变量名
实例名.实例变量名
举个例子来说明三个变量
class Text {
static int a;//类变量(静态变量)
int b;//实例变量
}
public class TextForVariable {
public static void main(String[] args) {
int a = 10;//局部变量
int b = 11;//局部变量
a=12;
b=13;
Text.a = 1;
Text text = new Text();
text.a = 2;
text.b = 2;
Text text1 = new Text();
text1.a = 3;
text1.b = 3;
System.out.println(a);
System.out.println(b);
System.out.println(Text.a);
System.out.println(Text.a);
System.out.println(text.a);
System.out.println(text1.a);
System.out.println(text.b);
System.out.println(text1.b);
}
}
输出结果为:
12
13
3
3
3
3
2
3
可以看到所有类变量的值为最后赋值的3; 实例变量可以被多次赋值; 局部变量只能有一次最终赋值。
2. 代码块 1. 静态代码块 (1) 定义
代码块也称为静态代码块,是类中独立于类成员的代码块
static{
}
1、static代码块只执行一次
2、静态块常用来执行类属性的初始化
3、静态块优先于各种代码块以及构造函数,一个类中可以有多个静态代码块,则按照书写顺序执行
4、静态代码快要独立于类成员,可以定义在类中的任何地方除了方法体中
5、静态代码可通过对象访问普通变量
(2) 举例
public class TestStatic {
private int b;
private static int a;
static {
TestStatic.a = 6;//此处可直接写成a=6
System.out.print(a + "\t");
TestStatic ts = new TestStatic();
ts.show();
ts.b=200;
System.out.print(ts.b+"\t");
}
public static void main(String[] args){}
static {
TestStatic.a=9;
System.out.print(a+"\t");
}
void show(){
System.out.print("abc"+"\t");
}
}
输出结果:
6 abc 200 9
(三)分析
只要包含关键字的类被加载,Java虚拟机就可以通过类名找到它们。 因此,可以在创建该类的任何对象之前访问该对象,而无需引用任何对象。 因此,静态代码块的存在是在类加载时自动运行的,而普通方法和静态方法则不能自动运行。 前者需要对象,后者需要在类加载后调用,因此代码块在所有方法之前执行。
三、this关键字 1.代表当前对象
当 this 出现在方法体中时,它可以代表当前类的任何实例对象。 Leaf类的方法中的this可以代表Leaf类中的任何对象。 只有调用该方法才能确定其代表的具体对象。 这时候谁调用这个方法,这就代表谁。
class Leaf {
private String color;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
public class TestThis {
public static void main(String[] args) {
Leaf f1 = new Leaf();
f1.setColor("红色");//此时setColor中的this代表的是f1这个实例
System.out.println("第一片叶子是:"+f1.getColor()+"的");
Leaf f2=new Leaf();
f2.setColor("黄色");//此时setColor中的this代表的是f2这个实例
System.out.println("第二片叶子是:"+f2.getColor()+"的");
}
}
同样的,出现在构造方法中也是一样的,例如:
class Student{
String name;
int age;
public Student(String name,int age){
this.name = name;
this.age = age;
}
}
public class TestThis {
public static void main(String[] args) {
Student s1 = new Student("李红",22);
Student s2 = new Student("王明",30);
}
}
(1)当局部变量和成员变量相同时,成员变量将被隐藏。 如果此时需要使用成员变量,则必须使用this来引用该成员变量
class Fruit {
String color = "绿色";
public void harvest() {
String color = "红色";
System.out.println("这种水果收割时是红色:" + color);//此时color是局部变量
System.out.println("原来是:" + this.color);//此时color是成员变量
}
}
public class TestFruit {
public static void main(String[] args) {
Fruit fruit = new Fruit();
fruit.harvest();
}
}
(2)通过this调用成员方法
void sing(){
System.out.println("我会唱歌");
}
void dance(){
this.sing();//可直接写成sing(),非静态调非静态时可直接调用
System.out.println("我也会跳舞");
}
2.调用当前类的其他构造函数
语法格式:
this([参数])
class People{
String name;
int age;
People(String name){
this.name=name;
}
People(String name,int age){
this(name);//调用了该类的带一个参数的构造方法
this.age=ge
}
四、类成员和实例成员的使用规则
如果修改一个方法,这个方法就变成静态方法或者类方法,可以通过类名直接访问。 没有方法修饰的是实例方法,需要通过对象来访问。 那么,如果类的成员变量和方法被修饰,则该成员统称为类成员或静态成员,否则称为实例成员。
1. 使用规则 2. 示例
public class TextStatic {
static String a = "abc";
String b = "java";
void printValue() {
System.out.println(a);
System.out.println(b); //正确,实例方法中能直接调用非静态变量和静态变量
this.b="2";//正确,非静态方法中可以使用this调用非静态方法;
}
public static void main(String[] args) {
System.out.println(a);//静态方法中可直接访问静态变量
// System.out.println(b); //错误,静态方法中不能直接调用非静态变量
TextStatic textStatic = new TextStatic();
System.out.println(textStatic.b);//静态方法中需要实例化对象才能访问非静态变量
textStatic.printValue();//静态方法中调用非静态方法也需要实例化对象
this.b="2";//错误,静态方法中不能使用this
}
}
五、final修饰变量 1.final修饰成员变量
由final修饰的成员变量只能被赋值一次,赋值后其值不能改变。 一般来说,初始值有两种指定方式。
(1)定义final修饰的变量时,一般会同时赋初值
final int FUNCTION = 7; //正确
final int FUNCTION;
FUNCTION=7;//错误
(2)被final修饰的成员变量如果定义时没有赋初值则必须在构造函数中赋值
public class ExampleDemo {
final float FUNCTION;//PI没有在定义的同时赋初值
ExampleDemo(){
FUNCTION=3.15f;//在构造方法中完成赋值
}
public static void main(String[] args){
ExampleDemo exampleDemo = new ExampleDemo();
System.out.println(exampleDemo.FUNCTION);
}
}
这种在构造方法中先定义后赋值的方式,在使用上提供了更大的灵活性。 这样的final成员变量可以根据不同的对象而有所不同,但可以保持相同的特性。
2.final修改局部变量
由final修饰的局部变量必须显式地指定一个初始值。 可以在定义时赋值初始值,也可以在后面的代码中赋值,但只能赋值一次。
public class ExampleDemo {
public static void main(String[] args) {
ExampleDemo exampleDemo = new ExampleDemo();
exampleDemo.test();
}
public void test() {
final int a;//局部变量a,需要的时候赋值
final int b = 8;//局部变量b,定义的同时赋值
a = 5;//只能赋值一次
System.out.println(a);
System.out.println(b);
}
}
三、总结
Final修饰的变量必须在使用前初始化,并且只能显式赋值一次。
public class ExampleDemo {
private final String A="final";
private final int B=30;
public static final int C=26;
public final int E;
//一个对象一个新的常量值
public ExampleDemo(int x){
E=x;
}
public static void main(String[] args) {
ExampleDemo exampleDemo = new ExampleDemo(2);
exampleDemo.C=50;//错误,final变量不能再次赋值
System.out.println(exampleDemo.A);
System.out.println(exampleDemo.B);
System.out.println(ExampleDemo.C);
System.out.println(exampleDemo.E);
ExampleDemo exampleDemo1 = new ExampleDemo(3);
System.out.println(exampleDemo1.E);//变量E因为对象的不同而不同
exampleDemo1.test();
}
public void test() {
final int a;//局部变量a,需要的时候赋值
final int b = 8;//局部变量b,定义的同时赋值
a = 5;//只能赋值一次
System.out.println(a);
System.out.println(b);
}
}