java 变量声明和this关键字的一些思考

变量的声明

  • 声明变量几乎是初学java最先接触到的一种语法了,但是在了解了继承和多态以后,我对声明变量感觉越来越陌生了。举个例子:int a=5;最开始的时候,我对这句话的理解只是声明了一个int 类型的变量,变量名为a,在栈中存了一个值为5,再多一点也不过是5的默认类型是int。
    到了引用类型,我开始思考一个问题,众所周知,在声明变量a,int这个类型之后那么变量所存的值就被限制了,如果给a赋值一个超过int类型范围的值,编译阶段就会报错。很显然,javac在执行的时候对类型是有判断的,这也是官方给java定义成静态语言的原因,每一个变量和表达式在编译时都具有已知的类型。
  • 那么如果这个变量是一个引用类型的变量的呢?特别是类类型的变量呢?我先定义一个class A
    然后a=new A();此时a在栈中存的是一个指向堆空间中对应的地址。但是A a;起了什么作用呢?尤其是A在声明变量的时候起了什么作用。
  • 现在我定义一个class B extends A 然后我声明A a=new B(); 我们可以尝试去调用a中的方法和变量,发现A中定义的方法可以调用,如果此方法在B中被重写,那么调用的B中重写的方法,原因是在堆中存放的方法实际上是方法区中这些方法的地址,存在一个方法索引表,当方法被重写后,这个索引表指向的方法位置就改变了。但是我要讨论的并不是这个,而是A对a做了什么,假设对于java而言,这个a只是用来存地址的,那么根本不需要去声明A,只要找到地址对应的对象不就行了,但是在继承中,父类的对象被先创建,然后子类独立的代码才会被创建。如果你把一个子类对象强转成父类的实例,你会发现对象的hashcode并没有变,所以强转某种意义上只是限制了对对象的访问,因为强转并没有创建新的对象,也没有影响其他访问原对象的过程,所以我认为A是对堆中访问类的一种标记,所以堆空间在创建一个类的实例的时候,应该也会对这个空间一个对应的标记,父类的变量访问的空间只能是父类对应标记的空间。重写的问题上面解释过,就不赘述了。
  • 那么这个话题延伸下去就要提到一个关键字:this。
    起初我认为this就是代表该类的对象,后来我经过一些尝试发现仅仅这样解释有些不合理的地方。

this

  • 首先在继承中,在父类中的this和子类中的this明显意义不同,所以我有一个想法:this如果是对当前类来说的关键字,如果父类和子类在堆中是包含关系我觉得这个this就明显存在“就近原则”this代表离这个关键字最近的类的对象。还有一种可能是,子类对象和父类对象是独立的两个对象,不是包含关系,而是连接关系,this代表的就是当前的这个类的对象,其实我更倾向于后一种说法。
  • 那么this等同于new关键字创建的对象吗?答案是不同的。
//举个例子
class A{
  int a=this.b;
  int b=5;
}
//此时new A().a=0;
class A{
{
b=5;
}
  int a=this.b;
  int b;
}
//此时new A().a=5;
class A{
  int a=this.b;
  int b=5;
  int c=this.b;
}
//此时new A().a=0 c=5;

如果仅仅理解成this等同于new一个对象,那么a就不可能对于0,因为当创建对象的时候,b=5这句话就会被加载,所以可以推出this此时找到的值,是b的默认值,也就是说遇到this关键字的时候,会去找这个变量,但是不会执行这个变量在这个this语句之后的相关的操作,换句话this在类加载的过程中如果有一些代码块是会对this有影响的,如果this在这个代码块的前面,那么this调用的类中变量是被代码块内代码影响之前的变量,反之,则是改变后的变量。所以如果说this就是当前对象,我认为不太客观,因为对象是类的实例,但是this在调用的时候,对象明显还没有被实例化。或者说是在类加载的过程中调用的。

类在加载的时候代码是从上到下加载的(此处暂且不谈静态和继承导致的加载顺序)
所以上述代码中的this.b;其实和int k(){ return b; }的效果是一样,如果把int a=k();那么b得到的结果和上面是一样的。
所以对于类的加载,我认为是在编译之后类的成员变量全部是默认值,不论有没有其他代码去改写这些变量,当类被加载的时候,这些方法才被调用,才会被赋值。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值