java关于静态与实例的区别和联系以及对象的理解。
初学java 将一些自己的所学所想记录在博客中,如有不对的地方欢迎指正。
最近学习了 成员变量 和局部变量, 以及在方法中成员变量和局部变量同名时该如何运用this调用成员变量的值, 由此产生了一些想法并用代码加以验证。
1. 我们将java中的类分为实体类和方法类,也叫抽象数据类型。
类就是包含了属性和方法的集合, 在属性里分为 实例变量 和静态变量。 方法中分为实例方法和静态方法。
java 是面向于对象的
我们可以用一个了类构造无数个对象,对象都是独立的一份拥有实例变量的实体。
2 关于 实例与静态的区别和关系
我们可以这样想, 当写好一个类 java在编译他们的时候, 因为没有构造对象 所以实例变量和实例方法都没有分配内存,便没有访问他们的入口地址。
但是静态的变量和方法会在类加载的时候就分配了内存, 所以静态的变量相当于为公用的,不被任何一个对象独享,也可以理解为它独立于对象之外,与任何一个对象都没有关系,但每一个对象可以访问独一无二的它们。
如图
a b两个静态变量和eat()方法编译时便已分配好了内存可以访问了,只此一份。
然后 This 对象1= new This() This对象2= new This() This对象3 = new This() This对象4= new This() ……
此时创建第一个对象的时候,便给一份实例变量分配了内存,有了入口地址,可以通过这个对象去访问变量 name age sex和方法study()了,其他对象的创建同理。
这四个对象会拥有name age sex实例变量,但各自拥有独立一份 并拥有相同的行为study()
在创建对象之前, 类加载时 ,会先加载静态的变量和方法 也就是说一开始就可以直接访问静态变量和方法,因为他们被加载了, 有了入口地址 这点与实例有很大的区别,实例必须创建对象 实例化才会分配内存有入口地址。
改变了一个对象的name sex age 不会影响另外一个对象的name sex age 但是如果改变了a 和b 通过任何一个对象或者在静态方法中去访问a和b的值都会改变
我们通常访问静态的变量和方法是用 类名+变量/方法名(class.xx) 的形式, 但是也可以用对象引用变量+变量/方法(a.xxx)的形式,其实他们是没有区别的。
所以综上所述
要明白 实例的方法和变量是对每一个对象而言的 静态的方法和变量可以把它看做是共用的,只此一份。
静态方法中不能直接操作实例的变量和方法,必须确定并通过对象的引用变量去访问
这是因为静态方法中本就只能操作和创建静态的变量和静态的方法,如果想在静态的方法中访问实例变量和实例方法,因为实例变量是对于每一个对象而言的,每一个对象都有一份。我们得知道到底访问的是哪个对象的实例变量和方法。实例化一个对象 就会有新的一份实例变量。所以在静态方法中访问它们需要知道具体是哪个对象,也就是确定对象的引用(地址)。
但是为什么实例方法中可以直接访问(不需要在确定对象的引用了)实例变量方法和静态变量方法呢?原因是如果此时我们在调用实例方法,说明此时肯定已经实例化好了一个对象,因为之前说过 实例方法和实例变量是需要实例化对象才能调用的(有了入口地址),如下图。
图中 我们实例化了一个对象 obj1 所以才能首次去访问实例方法 study(),在这个方法中,我们访问了实例变量,也访问了静态变量,调用了实例方法,也调用了静态方法。
这是因为,当我们实例化好对象obj1后,我们可以这样理解,之后都是在obj1这个对象的范围下操作的的。操作的实例变量就是这个对象自己的实例变量,操作的实例方法不用在前面加对象引用了,是因为就是在obj1这个对象范围下操作的,java编译时会自动的 在前面加上这个对象的引用。比如
this.name this.sleep()
this 代表的就是此时obj1。他们都是这个对象的引用( 地址)
而之前说过,静态变量和方法一开始就被加载好了 我们在任何地方都可以直接访问他们,此时的 a = 5 b =静态变量
可以想象成 this.a = 5 this.b = 静态变量 其实就是 Class.a = 5 Class. b = "静态变量”没有区别。 eat()方法同理。
3 关于成员变量 局部变量相同时,this的意义
如果在实例方法中,成员变量和局部变量相同,很简单
比如成员变量为 int a
局部变量 int a
在实例方法中我们访问成员变量就是 this.a 因为this代表的就是当前的对象。
如果成员变量是 static int a
也一样, this.a = class.a
此时我想到了一个问题 如果实在静态方法中呢?
首先要明白,this 本就代表的是对象,之前说过 静态方法与对象是独立开的,它和对象没有关系,
比如成员变量为 int a
局部变量 int a
在静态方法中,想要访问成员变量a 还可以用this.a 吗? 答案显然不行,因为之前说过 我们调用实例方法用this可以知道当前的对象是因为既然能用实例方法肯定说明已经构造出来了调用这个方法的对象,所以用this可以获取。但静态方法与对象无关,可以通过对象去访问静态方法,但是一定要清楚静态方法和对象是无关的。静态的东西都是一开始就有的,所以在静态方法里,this本身就是一个错误的东西,this到底代表那个对象?有人可能会说调用这个静态方法的对象。
这说明还是没有理解我的那句话 静态方法和对象是无关的,虽然可以通过对象去访问静态的变量和方法,但也只能说明静态是公用的,这种访问和通过类名访问是没有区别的,至少对于静态方法而言 它并不关心谁调用了它 它都认定是通过类名调用的,自然它也不知道调用了它的对象是谁,所以this就是错误的定义(在静态里)。
因此此时访问a ,this这个对象既然不存在 你就得确定一个对象的引用来访问它自己的a(可以通过把要访问a的对象传参进来)。
成员变量为static int a
局部变量 int a
这个就更简单了,静态方法中 局部变量a就是静态的 成员也是静态的 访问成员就通过类名加a访问 如果有确定的对象引用 也可以通过对象引用加a访问。
第一篇博客,记录成长,文笔不好,写完自己读了一遍都有点头大,如果有不同的理解欢迎赐教。