static无法访问非static变量和方法

static无法访问非static变量和方法

为什么static无法访问非static变量和方法?

static是类的成员,与对象无关,优先于对象的加载,也就是说一个类出现的时候,类里面的static就已经加载了,但是此时还没有去new对象,只有new了对象之后内存里面才加载非static成员,所以在没有new对象的时候,内存中的static是访问不到非static的成员。这也就是为什么在static方法里面访问非static方法时必须先new对象,然后再通过对象的应用来访问非static成员!

注意:this和super指的都是对象,this指的是当前对象,super指的是当前对象的父类对象。由于内有new对象,所以在static成员里面访问不到this与super。

从内存的角度来分析

内存里面各个区域所存放的元素如下:

stack(栈)
    存放基本类型的数据和对象的引用,即存放变量。
    如果存放的是基本类型数据(非静态变量),则直接将变量名和值存入stack中的内存中;
    如果是引用类型,则将变量名存入栈,然后指向它new出的对象(存放在堆中)。

heap(堆)
   存放new产生的数据。

data segment 也叫作方法区
    分为静态域和常量域。

    静态域
    存放在对象中用static定义的静态成员(即静态变量,同理,如果该静态变量是基本类型则将变量名和值存入静态域,如果是引用类型则指向new出的对象)。

    常量池
    存放具体的值,也就是变量所代表的值 。

code segment
存放代码。

 

下面我们一起看一个例子: 红色位置报错

==========================================

public class test20210121 {

    private String str1 = "abcd";
    private static String str2 = "static_abcd";


    public void func1 (){
        System.out.println(str1);
        System.out.println(str2);
        func2();
    }

    public static void func2 (){
        System.out.println(str1);    //此时没有new对象,func2在内存里面就找不到str1 = "abcd"变量,一般成员变量只用new对象之后才能和对象一起存在堆里面
        System.out.println(str2);
        func1();   //此时没有new对象,func2在内存里面就找不到func1方法,一般对象方法只有new对象之后才能在内存里面调用(调用的时候创建已经栈帧,jvm将栈帧入栈到栈里面)
        test20210121 test2021 = new test20210121();
        test2021.func1();

    }

    public static void func3 (String str){
        str.toLowerCase();
        System.out.println(str);

    }

    public void func4 (){
        func3(str1);  //此时没有new对象,func3在内存里面就找不到str1,所以不能直接运行。虽然没有new对象,但是func3在类加载的时候就已经加载在内存里面了,可以直接在内存里面找到func3
    }

    public static void main(String args[]){
        func3(str1);  //此时没有new对象,func3在内存里面就找不到str1
        test20210121 test2021 = new test20210121();
        test2021.func4();  //此时已经new了对象,又因为对象和对象的属性str1都在堆里面,所以func4里面的func3可以在内存里面找到str1

    }

}

=============================================================================

public class test20210124 {

    int i = 5;
    static int k = 2;

    public void m1(){
        i = i + k + m2(i, k);  //没有创建对象,此时的m2在内存里面访问不到 i ,只能访问到静态域里面的 k ,编译时不会报错,但是不能运行
        System.out.println(i);
    }

    public static int m2(int i, int j){
        return (int) (Math.pow(i, j));
    }

    public static void main(String[] args) {
        test20210124 test2021 = new test20210124();
        System.out.println(test2021.i);  //输出:5,已经创建了对象,i=5和对象都存放在堆里面
        test2021.m1();   //输出:32,已经创建了对象,m1里面的m2就可以在内存里面访问到i = 5
    }
}

================================================================================

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值