Java基础(三)static关键字

        本文主要介绍关于static关键字在java语言中的应用,从三个角度什么是static关键字、为什么设置static关键字和怎样用static关键字进行了说明,并补充了一些关于static关键字的练习。

一、static关键字是什么

        ①static修饰符修饰的代码属于类代码,没有static修饰的属于对象。

        ②static修饰符修饰的代码存储在方法区的静态常量池中,且属于类的东西是被对象所共享的(变量相当于共享的是内存空间,方法则是被调用(入栈与出栈))

二、Java为什么设置static关键字

        1、目的:因为要方便类去使用自己的方法和变量

        2、假设我们的方法和变量上面没有static关键字。

        如果方法和变量属于非静态,他们只有在对象当中才会被分配内存空间,那么也就是只能有对象才能调用。

        3、假设我们的方法和变量上有static关键字

        如果方法和变量属于静态,同时方法和变量会被存储在方法区的静态常量池中,并且能够直接被类调用(也能如上图被对象调用,因为对象来源于类,那么对象可以使用类的信息,但是不推荐)。

        从上一张图可以看出如果没有static关键字,那么类是不可以调用自己的属性和方法的,只能用对象去调用。

三、static怎样用?

   1、static修饰变量

        static修饰的变量属于类变量,存储在方法区的静态常量池当中,被所有对象共享。

        例1:

        代码

        运行该代码输出:

        分析:

        ①遇到代码问题首先画出堆栈内存图。

        ②name是被static修饰的,存储在方法区的静态常量池中,a1与a2存储在栈内存中,此时他们的address都为保定,name为admin。

        ③通过a1.name和a1.address对值进行修改,此时a1所指向的地址中address的值变为北京,静态常量池中的name值改为张三,然后通过a2.name和a2.address对值进行修改,此时a2所指向的地址中address的值变为上海,静态常量池中的name值改为石家庄。

2、static修饰方法

        (1)在static修饰的静态方法中无法调用非静态方法

        如何解决以main方法为例:如果一个方法想要被main方法调用,如何做?
                ①、给非静态方法添加static关键字
                ②、在main方法中创建对象,通过对象调用该非静态方法

        (2)在非静态方法中可以调用静态方法

       为什么在非静态方法中可以调用静态方法?

                因为hhh被static修饰属于类变量,存储在方法区的静态常量池当中,被所有对象共享。从形成角度来说, fff()方法想要表达的时候就已经创建好了对象,那么静态方法一定是存在的,因为有对象一定是有类的。

3、static修饰代码块

        在main方法执行之前运行目的是优化程序。

        例1:

        代码:

        输出:

        解释:

        首先寻找含有main()函数的类启动程序 然后进行扫描检查该类有没有父类,如果有则继续扫描父类(对父类重复上述操作),本代码发现父类Base没有父类。 接着先通过javac指令将Base.class文件加载到方法区,同时Base当中的static代码块执行。 再将ceshi.class文件加载到方法区,同时ceshi当中的static代码块执行。 最后main()入栈执行new ceshi()创建对象(在创建子类对象之前,应该先创建父类对象),先执行Base()构造器 在执行ceshi()构造器。

四、static关键字练习

        例1:

               代码:

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

                解释:

        画堆栈运行图,首先在静态常量池中放一个变量a,a的默认值为0,main执行,调用modify(a)方法入栈,注意该方法上的变量是局部变量,只在该方法中起作用。java只进行值传递,此时执行a++,然后出栈,最后输出a的值,注意此时的a是静态常量池中的变量a,值为0。

        例2:

                代码:

public class Demo  {
    public Demo(String aa){
        System.out.println("===="+aa);
    }
    static{
        System.out.println("11");
    }
    public static Demo demo=new Demo("+++");
    static{
        System.out.println("22");
    }
}
class Test{
    public static void main(String[] args) {

        Demo demo=new Demo("----");
    }
}

                结果:

                解释:

               ① main方法在哪就先扫描哪个类,扫描Test类发现没有父类,也没有static修饰的代码,那么编译Test类,并且将main方法入栈。

                ②执行new Demo("----"),在执行之前扫描Demo类,发现没有父类,所以编译Demo类

在编译过程中satick代码块按顺序优先执行

                ③首先输出11

                ④执行  public static ceshi ce=new ceshi("+++") ,此时会涉及到Demo构造方法,所以输出====+++

                ⑤输出22

                ⑥编译完毕 回到main方法中继续执行new Demo("----"),现在可以创建对象了,也就是到了运行阶段

                ⑦此时通过调用构造器构造对象====----

                

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值