文章目录
static
2024/8/22记
2024/8/22上午课
重难点摘要:
为什么在非静态方法当中可以调用到静态方法
方法区?静态常量池?类信息?内存空间?
为什么对象能调用到非静态变量
为什么对象能调用到静态变量
static关键字
1. static关键字是什么
①static修饰符修饰的代码属于类,没有static修饰符修饰的代码属于对象。
②定义的变量存储在方法区的静态常量池中。
2.java为什么要static关键字
因为要方便类去使用自己的方法和变量
举例和解释:
假设我们的方法和变量没有static修饰符修饰时。
①那么没有static修饰符修饰的方法和变量是属于对象的,只能用对象进行调用
②原因:没有static修饰符修饰的方法和变量的内存空间都是在对象中的(对象是堆里面的一块内存空间)
假设我们的方法和变量有static修饰符修饰时。
①只要被static所修饰的变量和方法,都会放在静态常量池里面——>开辟了内存空间——>能直接被类调用。
②并且也能被对象调用——>因为类是构成对象的模板,对象可以共享类的一些变量和属性
③所以设计static关键字是为了方便类去使用自己的方法和变量,如果没有static关键字,类是不能调用自己的方法和变量的。
3.static关键字怎么用
①static修饰符修饰变量
static修饰的变量叫做类变量,存储在方法区的静态常量池里面,被所有对象共享
public class A {
public static String name="admin";
public String address="保定";
public String toString(){
return "A{"+
"address="+address +'\''+
"name="+name +'\''+
'}';
}
}
public class Test {
public static void main(String[] args) {
A a1=new A();
A a2=new A();
a1.address="北京";
a1.name="张三";
a2.address="上海";
a2.name="石家庄";
System.out.println(a1.toString());
System.out.println(a2.toString());
}
}
②static修饰符修饰方法
- static修饰的方法无法调用到非静态方法
- 在非静态方法当中可以调用到静态方法
- 如果一个方法想要被main方法调用:
- 方法一:在非静态方法上加上static关键字。
- 方法二:在main方法当中创建对象,才能让对象调用该非静态方法。
- 那如果没有static修饰符修饰方法,并且想要被main方法调用:
- 只能在main方法当中创建对象,才能让对象调用该非静态方法。
为什么在非静态方法当中可以调用到静态方法
- 因为静态方法是属于类的,类里面的东西是共用的。
- 非静态方法想要表达的时候就已经创建好了对象——>有对象一定是有类的——>所以静态方法一定是存在的——>对象共享类里面的东西——>所以非静态方法当中可以调用到静态方法。
方法区?静态常量池?类信息?内存空间?
方法区:.class文件(可以叫做二进制的字节码文件)是存储在方法区中的。
.class文件:以二进制的形式存储类信息(无论是静态的,还是非静态的,都是放在这里的)
static修饰符修饰的变量以及方法:(也)存储在静态常量池里面(可以理解成备份,这么理解),这个是有内存空间的,也正是因为有独立的内存空间,所以才能使用它。没有内存空间的话,则不能被调用。
非static修饰的:以二进制的形式直接存储在方法区当中
再解释一下这里的说法——>什么叫做无论是静态的,还是非静态的,都以二进制的形式存储在.class文件中。又说static修饰符修饰的变量以及方法(静态的)是存储在静态常量池里面的。如何理解“备份”的这种解释。
public class A {
//在方法区的静态常量池里面分配一块内存空间,名字叫name,值叫张三
//实际上就是这个——》
public static String name = "张三";
//但是计算机看不懂
//那么就需要把它转换为相应的二进制
//计算机看懂了之后,文件仍然保留。(没有开辟内存空间,以信息形式存储)
//并且根据此命令在方法区的静态常量池里面分配一块内存空间,名字叫name,值叫张三
}
为什么对象能调用到非静态变量
有了“方法区?静态常量池?类信息?内存空间?”的知识,再解释为什么对象能调用到非静态变量。
堆栈内存图解释:
方法区中存储类信息(以二进制形式存储),
二进制的代码,并没有给类的信息分配独立的内存空间。
什么时候才能有独立的内存空间:对象在堆里面开辟空间,此时(类里面的name)才有了独立的内存空间,此时才能够调用它。
为什么对象能调用到静态变量
public class A {
public static String name = "张三";
}
public class Test {
public static void main(String[] args) {
A a = new A();
a.name = "sss";
A.name="ssssssss";
}
}
static修饰的信息,会被专门放在静态常量池里面(开辟内存空间了)。因为类是共享的,所以对象也可以调用到它。
③static修饰符修饰代码块
在main方法之前运行,目的是优化程序。
static修饰代码块
4.题①
public class A {
private static int a;
public static void main(String[] args) {
modify(a);
System.out.println(a);
}
public static int modify(int a){
return a++;
}
}
输出结果是什么?
所以输出结果是0。
4.题②
代码输出的结果是什么?( )
public class Test {
public int aMethod( ) {
static int i = 0;
i++;
return i;
}
public static void main (String args[]) {
Test test = new Test();
test.aMethod();
int j = test.aMethod();
System.out.println(j);
}
}
A. 0 B. 1 C. 2 D.编译失败
选d
因为 static不能修饰局部变量
4.题③
static class MyClass { // 注意:这是错误的,static不能用于直接声明类
int myVariable = 10;
void myMethod() {
System.out.println("Hello");
}
}
static不能用于直接声明类
4.题④
5.以下关于static代码块的说法哪个是错误的?
A. static代码块在类加载到JVM时执行
B. 一个类中可以有多个static代码块,它们按照在类中出现的顺序执行
C. static代码块在每次创建类的实例时都会执行
D. static代码块通常用于初始化静态变量
答案:c
jvm包括栈,堆,方法区
需要反复强调的知识点
- 对象是堆内存的一块内存空间
- 对象来源于类,那么对象可以使用类的信息
- 如果没有static关键字,那么类是不可以调用自己的属性和方法的,只能对象去调用
- 类是构成对象的模板,一个类可以生成多个对象
- 有了内存空间才能被调用