# static和this
# this 关键字
this可以看做一个变量,它是引用类型,存储在Java虚拟机堆内存的对象内部,this这个引用保存了当前对象的内存地址指向自身, 任何一个堆内存的java对象都有一个this,也就是说创建100个java对象则分别对应100个this。 this指向“当前对象”,也可以说this代表“当前对象”,谁调用实例方法,this就是谁,this可以使用在实例方法中以及构造方法中,语法格式分别为“this.”和“this(..)”。this不能出现在带有static的方法当中。
# this 实例方法中使用
// ThisZx.java
public class ThisZx {
public static String name = "名字";
public int no = 1;
public static void main(String[] args) {
// System.out.println(this);// 报错 无法从静态上下文中引用非静态 变量 this
// static 静态方法 通过类名.方法名调用
ThisZx.m();// 等同于 m()
// 非静态方法 通过new出来的对象名.方法名调用
ThisZx t = new ThisZx();//
t.m2();
System.out.println("--------------------------");
Student s = new Student("张三", 201813, "六(1)");
System.out.println("main --> " + s);
System.out.println("name --> " + s.getName());
System.out.println("--------------------------");
Student s2 = new Student("李四", 2020, "六(2)");
System.out.println("main --> " + s2);
System.out.println("name --> " + s2.getName());
System.out.println("--------------------------");
// static 静态方法和静态变量都是用 类名.方法名/变量名 访问
System.out.println(name); // 名字
System.out.println(t.no); // 1
}
public static void m() {
// System.out.println(this); // 报错 无法从静态上下文中引用非静态 变量 this
}
public void m2() {
System.out.println(this); // ThisZx@6d06d69c,只有 new 出来的对象才能访问到 this,this 指向的是 new 出来的对象
}
}
// Student.java
public class Student {
// 成员变量
private String name;
private int no;
private String className;
public Student(String name, int _no, String _className) {
System.out.println("Student构造方法 --> " + this);
this.name = name;
// this可以省略,前提是局部变量和成员变量名称不相同
no = _no;
className = _className;
}
public String getName() {
System.out.println("getName --> "+ this);
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
备注:
- this 表示当前对象的引用 也就是 通过 new 出来的对象
- this 无法在 static 静态方法中使用,因为调用 static 静态方法不需要对象,所以无法使用 this
- this 可以在实例方法中使用,代表当前对象
- 在当前实例方法中使用 this,可以忽略使用this,区分局部变量和实例变量时不能省略
# this(实际参数列表) 使用
this 的另外一种写法 this(实际参数列表),但必须写在构造方法的第一行,否则报错。
// ThisZx.java
public class ThisZx2 {
public static void main(String[] args) {
MobilePhone mb = new MobilePhone();
System.out.println(mb.getName());
}
}
// MobilePhone.java
public class MobilePhone {
private String name;
private double price;
public MobilePhone() {
// this(参数列表)代码复用 默认值,必需在构造函数第一行
this("iPhone", 699.00);
// this.name = "iPhone";
// this.price = 699.00;
}
public MobilePhone(String name, double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
备注:
- 主要记住 this(参数列表) 在写在构造方法的第一行,否则报错
# static 关键字
static是java语言中的关键字,表示“静态的”,它可以用来修饰变量、方法、代码块等,修饰的变量叫做静态变量,修饰的方法叫做静态方法,修饰的代码块叫做静态代码块。 在java语言中凡是用static修饰的都是类相关的,不需要创建对象,直接通过“类名”即可访问,即使使用“引用”去访问,在运行的时候也和堆内存当中的对象无关
声明为static的变量称为静态变量或类变量。可以直接通过类名引用静态变量,也可以通过实例名来引用静态变量,但最好采用前者,因为后者容易混淆静态变量和一般变量。 静态变量是跟类相关联的,类的所有实例共同拥有一个静态变量。 声明为static的方法称为静态方法或类方法。静态方法可以直接调用静态方法,访问静态变量,但是不能直接访问实例变量和实例方法。静态方法中不能使用this关键字,因为静态方法不属于任何一个实例。
# static 静态变量
java中的变量包括:局部变量和成员变量, 在方法体中声明的变量为局部变量,有效范围很小,只能在方法体中访问,方法结束之后局部变量内存就释放了,在内存方面局部变量存储在栈当中。 在类体中定义的变量为成员变量,而成员变量又包括实例变量和静态变量, 当成员变量声明时使用了static关键字,那么这种变量称为静态变量,没有使用static关键字称为实例变量
修饰符 class 类名{
//类体
static 类型 成员变量1;
static 类型 成员变量2;
}
2
3
4
5
// StaticSy.java
public class StaticSy {
public static void main(String[] args) {
// 类名. 访问静态成员变量
System.out.println(Man.sex); //true
Man m = new Man(123);
// 实例对象 访问静态成员变量,不建议这么做,容易混淆,静态变量和一般变量,建议使用 类名.
System.out.println(m.sex); //123
System.out.println(m.idCard); //123
Man m1 = new Man(101);
System.out.println(m1.idCard);
System.out.println(m1.sex);
Man m2 = new Man(102);
System.out.println(m2.idCard);
System.out.println(m2.sex);
Man m3 = new Man(103);
System.out.println(m3.idCard);
System.out.println(m3.sex);
System.out.println("----------------------------");
m3 = null;
System.out.println(m3.sex); // true
// System.out.println(m3.idCard); // 报错 java.lang.NullPointerException
//静态方法比较正式的访问方式
Man.printInfo(); // 男
//访问静态方法可以使用引用吗?并且空的引用可以吗?
m2.printInfo(); // 男
// m3 = null 还可以调用 printInfo
m3.printInfo(); // 男
}
}
// man.java
public class Man {
int idCard;
// 静态成员变量(静态变量)
// 性别(true表示男,false表示女)
static boolean sex = true;
public Man(int idCard){
this.idCard = idCard;
}
// 静态方法
public static void printInfo(){
System.out.println("-----" + (Man.sex ? "男" : "女") + "------");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
备注:
- 静态变量和静态方法 使用类名访问
- 通过 new 出来的引用对象访问也可以访问并且当引用对象赋值为 null 时也可以访问静态变量/方法而且不会出现空指针异常,但不建议这么做
# static 静态代码块
静态代码块在类加载时执行,并且只执行一次。静态代码块实际上是java语言为程序员准备的一个特殊的时刻,这个时刻就是类加载时刻,如果你想在类加载的时候执行一段代码,那么这段代码就有的放矢了。 例如我们要在类加载的时候解析某个文件,并且要求该文件只解析一次,那么此时就可以把解析该文件的代码写到静态代码块当中了。 静态代码块的语法格式:
修饰符 class 类名{
//静态代码块
static{
java语句;
}
}
2
3
4
5
6
public class StaticDmk {
static {
System.out.println(2);
// System.out.println(quantity);// 报错 非法前向引用,遵循代码自上而下顺序执行,先定义变量,再使用变量
}
int i = 100;
static int quantity = 200;
static {
System.out.println(1);
//System.out.println(i); // 报错 无法从静态上下文中引用非静态 变量 i
StaticDmk sd = new StaticDmk();
System.out.println(sd.i);
System.out.println(quantity);
// 调用静态方法
test();
// test2(); //报错 错误: 无法从静态上下文中引用非静态 方法 test2()
}
public static void main(String[] args) {
/**
* static 代码块先执行,再执行非static代码块,所以输出2、1、3 main
*/
System.out.println("main");
}
static {
System.out.println(3);
}
static void test(){
System.out.println("test");
}
void test2(){
System.out.println("test2");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
备注:
- 静态代码块可以访问静态变量和静态方法,不能访问非静态变量和非静态方法
- 静态代码块在类加载是只执行一次
# static 静态方法
有静态变量就有静态方法,方法是描述的是行为动作,在方法前加 static 修饰符称为静态方法,静态方法使用 类名.静态方法
调用,不需要实例化,因为没有实例变量,所以静态方法中没有 this,只有实例方法中才有 this,
一般用于编写 "工具类" 这样就不需要创建对象,直接使用 类名.静态方法
调用,方便使用
修饰符 class 类名{
修饰符列表 类型 变量名1;
修饰符列表 类型 变量名2;
public static 返回值类型 方法名 {
// 方法体
}
}
2
3
4
5
6
7
8
9
10
//CustomerTest.java
public class CustomerTest {
public static void main(String[] args) {
Customer c_zs = new Customer("张三");
c_zs.shopping();
Customer c_ls = new Customer("李四");
c_ls.shopping();
Utils.p(20);
Utils.p(20.00);
Utils.p(true);
Utils.p('A');
Utils.p("abc");
}
}
//Customer.java
public class Customer {
private String name;
public Customer(String name) {
this.name = name;
}
public void shopping(){
System.out.println(name + "正在购物");
pay();
}
public void pay() {
System.out.println(name + "正在支付");
}
}
// Utils.java
public class Utils {
public static void p(int data){
System.out.println(data);
}
public static void p(long data){
System.out.println(data);
}
public static void p(float data){
System.out.println(data);
}
public static void p(double data){
System.out.println(data);
}
public static void p(boolean data){
System.out.println(data);
}
public static void p(char data){
System.out.println(data);
}
public static void p(String data){
System.out.println(data);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54