Static关键字是什么
static修饰的代码属于类
定义的变量存储在方法区的静态常量池当中
java为什么要设置static关键字?
因为要方便类去使用自己的方法和变量
例如:
1.方法和变量上面没有static关键字
package Work1;
public class A {
public String name="张三";
public void run(){
System.out.println("跑得很快");
}
public void fly(){
System.out.println("飞得很高");
}
//这些代码以信息的形式存储在内存方法区当中(是二进制的代码),只有创建对象时,这些非静态的方法和变量才会有独立的存储空间,被对象调用
}
这些代码以信息的形式存储在内存方法区当中(是二进制的代码),只有创建对象时,这些非静态的方法和变量才会有独立的存储空间,被对象调用
package Work1;
public class Test {
public static void main(String[] args) {
//假设方法和变量上面没有static关键字
A a=new A();
a.run();
a.fly();
a.name="aaa";//只能由对象调用
//如果方法和变量属于非静态方法,他们只有在对象当中,才会被分配内存空间,那么也就是只能由对象才能调用
//如果没有static关键字,那么类是不可以调用自己的属性和方法的,只能用对象去调用
}
}
如果没有static关键字,方法和变量属于非静态方法,那么类是不可以调用这些属性和方法的,只能用对象去调用
堆栈内存图如下
方法和变量上面有static关键字修饰
public class A {
public static String name="张三";
public static void run(){
System.out.println("跑得很快");
}
public static void fly(){
System.out.println("飞得很高");
}
}
package Work1;
public class Test {
public static void main(String[] args) {
A a=new A();
a.run();
a.fly();
a.name="aaa";
//对象来源于类,那么对象可以使用类的信息,因此可以通过调用方法和变量
//可以直接用类调用
A.name="bbb";
A.run();
A.fly();
//因为在方法区的静态常量池当中由独立的内存空间
}
}
因为在方法区的静态常量池当中由独立的内存空间,可以直接用类调用。对象来源于类,那么对象可以使用类的信息,因此可以通过调用方法和变量 。
堆栈内存图:
Static关键字如何使用?
staic修饰变量
package Work1;
public class A {
//static修饰的变量属于类变量,存储在方法区的静态常量池当中,被所有对象所共享
public static String name="张三";
public String address="保定";
@Override
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="aaa";
a1.address="上海";
a1.name="bbb";
System.out.println(a1.toString());
System.out.println(a2.toString());
}
}
修饰方法
1.静态方法(static修饰的方法)无法调用非静态方法
解决方案:
1.在非静态方法上加上static关键字
2.在main1方法当中创建对象,让对象调用非静态方法
2.在非静态方法可以调用静态方法
原因:非静态方法想要表达,已经创建了对象,那么静态方法一定存在, 有对象一定有类
修饰代码块
1.在main方法运行之前运行,目的是优化程序
例1
程序执行流程:
1.首先main方法入栈
2.main方法会调用hhh方法,hhh方法会将静态常量池中的a的值赋给入参
3.a++入参的值变为1
4.然后hhh方法出栈
5.继续执行main函数中的System.out.println(a); 输出静态常量池当中a的值
例2
程序执行流程:
1.首先main方法入栈
2.创建一个A类的对象a1
3.调用及静态常量池当中的hhh()方法入栈
4.将对象a1的私有属性a赋给入参
5.执行hhh()方法当中的return a++:入参加1变为1
6.hhh()出栈
7.继续执行main方法当中的
System.out.println(a);输出对象a1的私有属性a
例3
package Work1;
public class E {
public E(String a){
System.out.println("===="+a);
}
static {
System.out.println("11");
}
public static E e=new E("+++");
static{
System.out.println("22");
}
}
class T {
public static void main(String[] args) {
E e=new E("----");
}
}
程序执行的流程:
扫描-------->加载(编译)--------->运行
main在哪里先扫描哪个类
1.首先扫描Test类,发现其没有父类,也没有static修饰的代码,那么先编译Test类,并且将main方法入栈
2.执行new E("----"); 在执行之前,先扫描E类发现其没有父类,在编译的过程中,static修饰的代码块按顺序优先执行
3.static {
System.out.println("11");
}先执行该static代码块,输出“11”
4.再执行public static E e=new E("+++");此时会涉及到E类当中的构造方法,输出“====++++”
5.最后执行
static{
System.out.println("22");
}输出“22”
6.编译阶段完毕,回到main方法当中,继续执行new E("----");现在可以创建对象,真正运行
7.通过调用构造器创建对象,输出“====----”
例4
package work2;
public class Test {
public static void main(String[] args) {
Person p1=new Person();
Person p2=new Person();
p1.name="李四";
p1.address="北京";
p2.name="张三";
p2.address="上海";
System.out.println(p1.toString());
System.out.println(p2.toString());
}
}
package work2;
public class Person {
public String name;
//static修饰符修饰的代码属于类代码,没有static修饰的代码属于对象
public static String address="保定";
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
"address='" + address + '\'' +
'}';
}
}
类信息是存储在方法区当中的
static修饰的代码会存储在方法区的静态常量池当中
程序执行流程
1.main方法入栈
2.创建p1 p2两个对象
3.最开始将p1,p2两个对象的name均为“张三”
4.给p1变量的name赋值,address赋值
5.给p1变量的name赋值,address赋值
如果static修饰方法,方法也是共享的,类似于工具被使用
例5
package work2;
public class Test {
public static void main(String[] args) {
Person p1=new Person();
Person p2=new Person();
p1.name="李四";
p1.address="北京";
p1.run("100");
p2.name="王五";
p2.address="上海";
p2.run("200");
System.out.println(p1.toString());
System.out.println(p2.toString());
}
}
、
package work2;
public class Person {
public String name;
//static修饰符修饰的代码属于类代码,是被对象所共享的,没有static修饰的代码属于对象
public static String address="保定";
public static void run(String num){
System.out.println("跑了"+num+"米");
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
"address='" + address + '\'' +
'}';
}
}
run方法入栈执行
static修饰的变量是被所有类所共享的
欢迎点赞,收藏,和关注呦!!!