this指针与类方法的调用机制

Java编译器在初始化对象的时候,为同一类型(即同一类)的对象在栈区存储了函数副本(即使对static方法也是如此)。

为了区别不同对象,新对象生成时,会由编译器生成一个引用变量进行指向。

该引用变量指向堆区中存储具体对象域属性值的内存区域,即同属一类的对象,共享其类定义的函数。

既然函数为公用的,那么当同一方法被不同对象调用的时候,如何正确的区别调用此方法的对象以产生正确的行为呢?

Example:

class Test

{

  int num;

  Test(int i)

  {num=i;}

  print()

  { System.out.printl(num);}

}

main()

{

  Test t1=t1(1);

  Test t2=t2(2);

  t1.print();

      t2.print();

 }

Test类具有两个对象 t1、t2,此处它们都调用了print()方法,根据print方法的定义,它们需要打印出自己的属性num的数值。

那么print方法是如何被调用,以保证被指向正确的内存空间的呢?我们调用函数的时候并没有显示的给出对象引用作为参数啊!

实质是:我们在通过对象调用方法的时候,编译器暗自的把“所操作对象的引用”作为第一个参数传递给了print。

e: t1.print();  ----->      Test.Print(t1);//此处仅作为理解,并无实际意义

这样一来,方法就能准确的的根据编译器传递来的对象引用确定操作的对象,从而避免了出错。

e: print()----->print(){System.out.print(this.number)}//此处的this关键字(C++中称this指针)代表了执行该方法的对象。

this关键字并不常用,但遇到要将调用的对象作为范围值返回的情况,this还是很重要的。

Example:

class Dog

{

  String name;

  Dog(String dogname){dogname=name};

  Dog bark()

 {

  System.out.printl(name+"is barking");

      return this;

  }

}

mian()

{

  Dog dog=new Dog("Happy");

     dog.bark().bark().bark();

}

调用bark()方法后,通过this指针返回调用对象本身,从而可以实现对bark()方法的无限调用!

在java中除静态方法外,其余的方法调用一定要与其调用对象联系在一起。

同一个类中,方法和域的操作都无需指明调用对象, 但是在一个类中调用另一个类得方法(静态方法、导出类调用基类方法除外),一定要指明调用对象。

值得一提的是static方法,static方法不能操作除static对象的域成员(static成员不能算是对象的域成员),static方法不需要this指针,故其不需要对象支持!

static方法一般提供一些全局的基本操作(在C++中称为全局方法),但是在Java中不允许脱离类而单独的存在方法,故将其放在类中做全局方法。

由于static方法,不能访问对象的域成员,故一般其需要的参数由调用的时候全部给出。

如 :

Package MathMethod

Class MathAdd

{

  static double add(ball b1, ball b2){ return b1.diameter+b2.diameter ;}

}

此方法中就将计算两个球的总直径长度作为了一个静态方法,并将两个球的对象的引用作为参数传入。

(这是非常重要的,非static方法是隐式传递this指针,而static中必须显示给出对象引用,可以据此灵活编写静态方法)

由于static方法需要依附于任何对象进行调用,鼓起调用格式可以直接为   类名.static方法名。

java中的包机制,给予了其一种更为方便的调用方法,允许像C++中的全局方法一样方便的对其进行调用。

Example:  上例中add方法的包路径为:  MathMethod.MathAdd.add;

由于add是静态方法,我们在别的包内可以直接调用它,只需要静态import 包。

e: Package Ballcal

import static MathMethod.MathAdd.*;

class Ball

{

     double diameter;

     Ball(float dia){diameter= dia};

     addBall(Ball two)

    {

   add(this, two);

     }

}

由于使用了import static添加包,可以实现对add方法的直接访问。(注意添加包的路径,一定是该方法根目录以上的目录)

原文地址:https://www.cnblogs.com/airwindow/p/2553142.html