java方法及this关键字原理分析详解

目录
  • 步骤1 、给顾客增加一个吃饭的方法
  • 步骤 2 、 没有加static的属性和方法,一定需要先new对象
  • 步骤 3 、 用new出来的对象去执行eat方法
  • 步骤 4 、 怎么理解c.eat()
  • 步骤 5 、 消息接受器
  • 步骤 6 、 如果有两个顾客?
  • 步骤 7 、 答案
  • 步骤 8 、其实有个this
  • 步骤 9 、 在eat方法里面直接使用this
  • 步骤 10 、 构造方法
  • 步骤 11 、 总结:this的意义是什么?
  • 步骤 12 、 道理我都懂,那static又是什么?
  • 步骤 13 、 本节完整源码

java类的方法,我特别喜欢《java编程思想》里面的描述,这本书说java类之间的相互通信是通过消息。比如顾客类的对象调用一个eat方法,可以看成是我们向顾客类发送了一条消息,命令他去吃饭。

步骤1 、给顾客增加一个吃饭的方法

假设我们有一个顾客类:

class Customer {
	String name;		// 客户姓名
	String sex;		//性别
	String birthDate;	//生日
	String phoneNumber;	//电话号码
        int status;	//客户状态(1:正常,2:不正常)
        void eat(){
           System.out.println("eating...");
        }

}

void代表方法没有返回值。

步骤 2 、 没有加static的属性和方法,一定需要先new对象

这是一句口诀,new的意思是新建一个对象,Customer类只是一个声明式的东西,不是真实存在的对象。
只要你没有加static,就必须要在运行的时候创建了对象,才可以使用!

说得武断一点,只要你没有加static,你要运行eat方法,就必须要new一个对象。

至于为什么,现在先不管,就这么强记一下吧。

步骤 3 、 用new出来的对象去执行eat方法

class Demo {
   public static void main(String[] args){
		Customer c = new Customer();
                c.eat();
   }
}

运行,就可以看到eat方法被调用了。

步骤 4 、 怎么理解c.eat()

c是顾客对象的一个引用,或者叫指针。c就是一个标记,本身不会保存顾客对象的数据,但是我们操作c,就和操作顾客对象是一样的。

这行代码代表我们向这个顾客发送了一条吃饭消息,顾客很聪明的,一下子就懂了,于是他就用一个句点 . 加上eat(方法名),再打一个圆括号的方式,执行了这个方法。

这是一次成功的通讯。

步骤 5 、 消息接受器

一个类里面的方法,我们可以把它称为​​消息接收器,这样非常有利于理解。

步骤 6 、 如果有两个顾客?

问个问题,如果有两个顾客,一个叫亚瑟,一个叫安琪拉。那么他们调用的eat方法是相同的还是不同的。

如果这个出面试题,是很有区分度的。

步骤 7 、 答案

答案是相同的方法,没想到吧。
原因是类加载器把class文件加载到虚拟机,内存的划分会把类的所有方法都放到一个叫做方法区的地方。不管你new多少个对象,调用的都是同一个方法。因为如果你每new一个对象,都专门开辟一个内存空间来存放方法的话,未免也太浪费了。

现在就有一个新的问题,既然方法是同一份,我怎么知道是谁呢?

步骤 8 、其实有个this

事情的真相是这样的…
Demo.java被javac命令编译成Demo.class和Customer.class,然后运行的时候,首先是类加载器去加载Demo.class,发现还用到了Customer.class,于是顺便把Customer.class也加载了。

在这个例子中,JVM里面有两个地方需要我们关注,一个是堆,一个是方法区。

什么是堆?堆是一块存放对象的区域,你每次new一个对象,这个对象就是放在堆里面。比如有这样的代码:

class Demo {
   public static void main(String[] args){
		Customer c1 = new Customer();
		Customer c2 = new Customer();
		c1.name = "亚瑟";
		c2.name = "安其拉";
   }
}

我们new了两个对象,其中c1和c2是他们的引用,这两个对象是放在堆里面的。

而eat方法,是放在方法区,只有一份。

然后重头戏来了,当你用其中某一个对象去调用eat方法的时候,其实会传过去一个this。

c1.eat();

this会神不知鬼不觉地作为eat方法的参数,传入eat方法。
每一个对象都有一个this,this并不是你设置的某个属性,而是java给每一个类都设置的标记,你察觉不到它的存在,但是它一直都在。

步骤 9 、 在eat方法里面直接使用this

我们在eat方法里面直接使用this,就是这样的:

void eat(){
   System.out.println(this.name + " eating...");
}

效果:

其实,它的底层是这样的,虽然我们不能这么写:

void eat(this){
   System.out.println(this.name + " eating...");
}

我们在方法里面调用某个变量,这个变量要么就是参数传进来的,要么就是这个类的属性,这个你同意不?基于这个常理,这个this不是我们定义的属性,那么只能是参数传进来的。只不过,这个过程是JVM做的,我们察觉不到。

步骤 10 、 构造方法

每一个类都有构造方法,写法是这样的。

public Customer(){

}

这是空的构造方法,你不写也没事,就算不写也会有这么一个方法。构造方法的作用就是在你new对象的时候,直接调用。

记住一个口诀:

1.类名打括号 = 调用构造方法,左边一定会有个new。
2.方法名打括号 = 调用这个方法,默认传入一个this(没有static的情况)

3.方法名打括号 = 调用这个方法,不传入this(有static的情况)

​现在再回过头来看new的语句,是不是对上了?

Customer c1 = new Customer();

步骤 11 、 总结:this的意义是什么?

因为方法是独一份,所有类的对象共享这些方法,JVM为了搞清楚到底是谁去调用某个方法,就在每一个类里面维护一个this。当类被实例化(就是new的时候),这个this就指向这个对象,然后在调用方法的时候,隐式地传入this,就可以在那个方法中获取到当前真实对象的数据了。

就有点像什么呢,有点像花名。

什么叫花名,比如小区的物业会设置一个花名,他们对外会宣称,管理1-10栋的物业管家的名字是小芳,这个小芳就是花名。这是一个虚拟的名字,业主也只知道物业管家是小芳,但是小芳可能今天是张三,明天是李四。张三李四都离职了,王五成为物业管家,对外的说法也是他叫管家小芳。

物业设置管家这个职位,并不知道究竟谁来做,于是先设置好,管家就叫做小芳。小芳就相当于this,只有等到张三来任职了,这个this就是张三。张三跑路,李四来了,这个this就是李四。

步骤 12 、 道理我都懂,那static又是什么?

我们已经不止一次提到static了,static到底是啥啊,别急,下节我们来分享,先把这一节的知识点消化一下吧。

步骤 13 、 本节完整源码

class Customer {
	String name;		// 客户姓名
	String sex;		//性别
	String birthDate;	//生日
	String phoneNumber;	//电话号码
	int status;	        //客户状态(1:正常,2:不正常)
	public Customer(){

	}
	void eat(){
	   System.out.println(this.name + " eating...");
	}
}
class Vip {
}
class Demo {
   public static void main(String[] args){
		Customer c1 = new Customer();
		Customer c2 = new Customer();
		c1.name = "亚瑟";
		c2.name = "安其拉";
		c1.eat();
   }
}

视频讲解:

Java对this的理解

Java中关于成员方法的讲解

以上就是java方法及this关键字原理分析详解的详细内容,更多关于java方法及this关键字的资料请关注我们其它相关文章!

(0)

相关推荐

  • 深入理解java中this关键字的使用

    一,表示类中属性 1,没有使用this的情况 class Person{ // 定义Person类 private String name ; // 姓名 private int age ; // 年龄 public Person(String name,int age){ // 通过构造方法赋值 name = name ; age = age ; } public String getInfo(){ // 取得信息的方法 return "姓名:" + name + ",年龄

  • Java基础之this关键字的使用

    一.this关键字的作用 this关键字除了可以强调本类中的方法还具有以下作用. 1.表示类中的属性 2.可以使用关键字调用本类中的构造方法 3.this表示当前对象 1.1表示类中的属性 package thiss; class Person{ private int age; private String name; public Person(int age,String name){ this.age=age;//为类中的age属性赋值 this.name=name;//为类中的name

  • Java中方法使用的深入讲解

    方法的使用 1.方法的基本用法 什么是方法,方法就是一个代码片段,类似于C/C++ 语言中的"函数". 1.1方法存在的意义: 是能够模块化的组织代码(当代码规模比较复杂的时候). 做到代码被重复使用, 一份代码可以在多个位置使用. 让代码更好理解更简单. 直接调用现有方法开发,不必重复造轮子. 1.2方法定义语法 基本语法: // 方法定义 public static 方法返回值 方法名称([参数类型 形参 ...]){ 方法体代码; [return 返回值]; } // 方法调用

  • Java的this关键字的使用与方法的重载相关知识

    Java this关键字详解 this 关键字用来表示当前对象本身,或当前类的一个实例,通过 this 可以调用本对象的所有方法和属性.例如: public class Demo{ public int x = 10; public int y = 15; public void sum(){ // 通过 this 点取成员变量 int z = this.x + this.y; System.out.println("x + y = " + z); } public static vo

  • 彻底理解Java中this 关键字

    this关键字再java里面是一个我认为非常不好理解的概念,:)也许是太笨的原因 this 关键字的含义:可为以调用了其方法的那个对象生成相应的句柄. 怎么理解这段话呢? thinking in java里面有这么一个例子 有两个同一个类型的对象,分别叫做a和b,那我们怎样区别在调用方法f()的时候,是谁再调用这个方法呢? 例如: class Banana { void f(int i){ /***方法主体*****/ } } Banana a = new Banana();//生成Banana

  • 在Java编程中定义方法

    方法包含一个方法头和一个方法体.下面是一个方法的所有部分: 修饰符:修饰符,这是可选的,告诉编译器如何调用该方法.定义了该方法的访问类型. 返回值类型 :方法可能会返回值.returnValueType是方法返回值的数据类型.有些方法执行所需的操作,但没有返回值.在这种情况下,returnValueType是关键字void. 方法名:是方法的实际名称.方法名和参数表共同构成方法签名. 参数类型:参数像是一个占位符.当方法被调用时,传递值给参数.这个值被称为实参或变量.参数列表是指方法的参数类型.

  • java方法及this关键字原理分析详解

    目录 步骤1 .给顾客增加一个吃饭的方法 步骤 2 . 没有加static的属性和方法,一定需要先new对象 步骤 3 . 用new出来的对象去执行eat方法 步骤 4 . 怎么理解c.eat() 步骤 5 . 消息接受器 步骤 6 . 如果有两个顾客? 步骤 7 . 答案 步骤 8 .其实有个this 步骤 9 . 在eat方法里面直接使用this 步骤 10 . 构造方法 步骤 11 . 总结:this的意义是什么? 步骤 12 . 道理我都懂,那static又是什么? 步骤 13 . 本节

  • Java中注解与原理分析详解

    目录 一.注解基础 二.注解原理 三.常用注解 1.JDK注解 2.Lombok注解 四.自定义注解 1.同步控制 2.类型引擎 一.注解基础 注解即标注与解析,在Java的代码工程中,注解的使用几乎是无处不在,甚至多到被忽视: 无论是在JDK源码或者框架组件,都在使用注解能力完成各种识别和解析动作:在对系统功能封装时,也会依赖注解能力简化各种逻辑的重复实现: 基础接口 在Annotation的源码注释中有说明:所有的注解类型都需要继承该公共接口,本质上看注解是接口,但是代码并没有显式声明继承关

  • Java CompletableFuture实现原理分析详解

    目录 简介 CompletableFuture类结构 CompletableFuture回调原理 CompletableFuture异步原理 总结 简介 前面的一篇文章你知道Java8并发新特性CompletableFuture吗?介绍了CompletableFuture的特性以及一些使用方法,今天我们主要来聊一聊CompletableFuture的回调功能以及异步工作原理是如何实现的. CompletableFuture类结构 1.CompletableFuture类结构主要有两个属性 pub

  • java设计模式责任链模式原理案例详解

    目录 引言 责任链模式定义 类图 角色 核心 示例代码 1.对请求处理者的抽象 2.对请求处理者的抽象 3.责任链的创建 责任链实现请假案例 案例类图 可扩展性 纯与不纯的责任链模式 纯的责任链模式 不纯的责任链模式 责任链模式主要优点 职责链模式的主要缺点 适用场景 模拟实现Tomcat中的过滤器机制 运行过程如下 分析Tomcat 过滤器中的责任链模式 引言 以请假流程为例,一般公司普通员工的请假流程简化如下: 普通员工发起一个请假申请,当请假天数小于3天时只需要得到主管批准即可:当请假天数

  • java中注解机制及其原理的详解

    java中注解机制及其原理的详解 什么是注解 注解也叫元数据,例如我们常见的@Override和@Deprecated,注解是JDK1.5版本开始引入的一个特性,用于对代码进行说明,可以对包.类.接口.字段.方法参数.局部变量等进行注解.它主要的作用有以下四方面: 生成文档,通过代码里标识的元数据生成javadoc文档. 编译检查,通过代码里标识的元数据让编译器在编译期间进行检查验证. 编译时动态处理,编译时通过代码里标识的元数据动态处理,例如动态生成代码. 运行时动态处理,运行时通过代码里标识

  • Java包装类的缓存机制原理实例详解

    这篇文章主要介绍了Java包装类的缓存机制原理实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 java 包装类的缓存机制,是在Java 5中引入的一个有助于节省内存.提高性能的功能,只有在自动装箱时有效 Integer包装类 举个栗子: Integer a = 127; Integer b = 127; System.out.println(a == b); 这段代码输出的结果为true 使用自动装箱将基本类型转为封装类对象这个过程其实

  • 简单了解Java方法的定义和使用实现详解

    这篇文章主要介绍了简单了解Java方法的定义和使用实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.概念 Java语言中的"方法"(Method)在其他语言当中也可能被称为"函数"(Function).对于一些复杂的代码逻辑,如果希望重复使用这些代码,并且做到"随时任意使用",那么就可以将这些代码放在一个大括号"{}"当中,并且起一个名字.使用代码的时候,直接找到名

  • JAVA中的final关键字用法实例详解

    本文实例讲述了JAVA中的final关键字用法.分享给大家供大家参考,具体如下: 根据上下文环境,java的关键字final也存在着细微的区别,但通常指的是"这是无法改变的."不想改变的理由有两种:一种是效率,另一种是设计.由于两个原因相差很远,所以关键子final可能被误用. 接下来介绍一下使用到final的三中情况:数据,方法,类 final数据 许多编程语言都有某种方法,来向编译器告知一块数据是恒定不变的.有时数据的恒定不变是很有用的,例如: 1. 一个编译时恒定不变的常量 2.

  • MyBatis Plus插件机制与执行流程原理分析详解

    MyBatis Plus插件 MyBatis Plus提供了分页插件PaginationInterceptor.执行分析插件SqlExplainInterceptor.性能分析插件PerformanceInterceptor以及乐观锁插件OptimisticLockerInterceptor. Mybatis 通过插件 (Interceptor) 可以做到拦截四大对象相关方法的执行 ,根据需求完成相关数据的动态改变. 四大对象是: Executor StatementHandler Parame

  • java编程FinalReference与Finalizer原理示例详解

    之前写了一篇java编程Reference核心原理示例源码分析的文章,但由于篇幅和时间的原因没有给出FinalReference和Finalizer的分析.同时也没有说明为什么建议不要重写Object#finalize方法(实际上JDK9已经将Object#finalize方法标记为Deprecated).将文章转发到perfma社区后,社区便有同学提出一个有意思的问题?"Object#finalize如果在执行的时候当前对象又被重新赋值,那下次GC就不会再执行finalize方法了,这是为什么

随机推荐