a1.a赋值后 class A中的a 会被改变吗》》》
不改变,应该说a1中的a改变了,A是一个类,a1是A实例化的一个对象
比如a1.a = 1;只是表示a1这个对象中的a值变化了。与A没什么关系,除非你的A里的a是个静态的变量,那么在实例化的时候,内存里始终只有一个变量a,它的值就会被改变。
不改变,应该说a1中的a改变了,A是一个类,a1是A实例化的一个对象
比如a1.a = 1;只是表示a1这个对象中的a值变化了。与A没什么关系,除非你的A里的a是个静态的变量,那么在实例化的时候,内存里始终只有一个变量a,它的值就会被改变。
实例化后,也就是用了new运算符号,在堆内存建立一个对象,对象是一块区域,里面包含着每个属性2.用private int a ; 就不会改变了
数据私有很重要
但在初始化对象之后,不是每个对象都有他本身的成员变量和方法空间吗,它不会覆盖,我理解,但是对于static 的成员变量和方法,难道他的对象就不是有各自的一片空间了吗?
|——|
| |对象1的成员变量和方法空间
| |
|——|
| |
| |
———|——|
| |
|——|对象2的成员变量和方法空间
| |
| |
———他们各自占各自的空间,怎么会覆盖呢》
Circle a=new Circle();
a=b;
|——|
|变量| <-------a
| | <-------b
|——|
|方法|
| |
———
对吗?
还有ClassLoader之类的东西
请教高手解答
1.在未实例化之前Account类占内存空间吗?
答: 在未实例化之前Account类不会占用任何空间,因为没有产生任何对象和对象的引用。
这个问题你得首先明白对象中的方法和成员变量在分配空间后的分配情况。2.初始化后有两个对象,各个对象中的方法和成员变量也都占另外一片空间吗?
答: 这个问题就是上面我要说的,两个对象中的成员变量是公有的,而方法是取决于你什么时候私有
取决于你什么时候去调用它。如果Account类中方法和成员变量都是静态的,有区别吗?
答: 有区别,静态的成员变量是你在实例化第一个类的对象之前调用的.而且他只被初始化一。 静态成员变量还相当充当于c或者c++里面的全局变量,如果你要用全局变量,在java里面一半来说都是静态的.静态方法是你在调用这个方法的时候不要实例化任何对象,就可以调用。对于继承关系的成员变量和方法又怎样呢?
答:静态的成员变量在任何时候都只是初始化一次.继承也一样.
静态的方法能不能重写没有试过。在书山也没有看过.a1.a赋值后 class A中的a 会被改变吗?
答:因该说对象a1中的变量a的值改变。
class Rectangle
{
int width;
int length;
Rectangle()
{
width=5;
length=10;
System.out.println("this is a construcor of Rectangle");
}
int area()
{
return width*length;
}
}
class R1
{
public static void main(String[] args)
{
Rectangle tt=new Rectangle();
tt.width=40;
tt.length=60;
System.out.println(tt.width);
System.out.println(tt.length);
System.out.println(tt.area());
Rectangle tt1=new Rectangle();
System.out.println(tt1.width);
System.out.println(tt1.length);
System.out.println(tt1.area());
}
}
假如初始化话对象后,类不占空间,我初始化一个对象,可以把类中的成员变量和方法考贝到第一个对象中,执行tt.width=40;
tt.length=60;后,也就是原来变量和方法都不复存在,在初始化第二个对象的时候,他怎么还能打印
this is a construcor of Rectangle
5
10
50
,他这些数据从何而来。上面的程序的打印结果:
this is a construcor of Rectangle
40
60
2400
this is a construcor of Rectangle
5
10
50
Press any key to continue...
先回答楼主第一个问题吧,实例化之后在堆中开辟一段内存来存储这个对象,所有针对此对象的修改都是修改这段内存区域的数值,和class有什么关系?
比如楼主的a1和a2:
<<
| HEAP |
+---------------------+
| |
| +-----------------+ |
a1----->| | A (a1) | |
| +-----------------+ |
| | int a(4byte) | |<---- a1.a
| | int b(4byte) | |
| +-----------------+ |
| |
| +-----------------+ |
a2----->| | A (a2) | |
| +-----------------+ |
| | int a(4byte) | |
| | int b(4byte) | |
| +-----------------+ |
| |
>>
在内存中大约就是这么一个状况,你修改的a1.a就是修改上图中相应的位置而已,对其他的地方都不会造成影响。
加载完类之后,并不会占用什么新的堆空间,知道这个类被实例化,实例化的时候才会在堆中开辟一段空间来存储新的对象,每实例化一次,就会申请一段新的空间来存储。PS,能够申请新的对象空间应该说只有以下三种方式:
(1) constructor
(2) clone
(3) serialize楼主你后面的例子:
<<
Rectangle tt=new Rectangle();
Rectangle tt1=new Rectangle();
>>
明明是实例化了两次,申请了两段空间,互相之间更本就没有干涉。。
<<
假如初始化话对象后,类不占空间,我初始化一个对象,可以把类中的成员变量和方法考贝到第一个对象中,执行tt.width=40;
tt.length=60;后,也就是原来变量和方法都不复存在,在初始化第二个对象的时候,他怎么还能打印
>>
至于这段话,根本就是不知所云。。
假如初始化话对象后,类不占空间,我初始化一个对象,可以把类中的成员变量和方法考贝到第一个对象中,执行tt.width=40;
tt.length=60;后,也就是原来变量和方法都不复存在,在初始化第二个对象的时候,他怎么还能打印
>>
关于这段,我认为楼主还是把对象和类搞混了。当它初始化第一次后,也就是Rectangle tt=new Rectangle();的时候,先创建了一个Rectangle的对象tt。
| |
| +-----------------+ |
tt----->| | Rectangle (tt) | |
| +-----------------+ |
| | int width | |<---- tt.width == 5
| | int length | |<---- tt.length == 10
| +-----------------+ |
然后,对对象tt赋值tt.width=40;tt.with=60后内存中就变为了
| +-----------------+ |
tt----->| | Rectangle (tt) | |
| +-----------------+ |
| | int width | |<---- tt.width == 40
| | int length | |<---- tt.length == 60
| +-----------------+ |
而当再次初始化Rectangle时,Rectangle tt1=new Rectangle();内存中变为
| +-----------------+ |
tt----->| | Rectangle (tt) | |
| +-----------------+ |
| | int width | |<---- tt.width == 40
| | int length | |<---- tt.length == 60
| +-----------------+ |
| +-----------------+ |
tt1---->| | Rectangle (tt1) | |
| +-----------------+ |
| | int width | |<---- tt1.width == 5
| | int length | |<---- tt1.length == 10
| +-----------------+ |
通过上面的图,应该了解到对象并不影响class中的值,而且每次初始化对象都互不影响的。
public static void main( String[] args){}
的类会占用内存.
{
int a;
String b;
boolean c;
public xx(){
}}虽然构造函数看上去什么都没做,
但是只要它一执行,
它的成员就被分配了空间.
一个对象的应用就生成了.
去看看inside jvm 吧
静态类 以及 静态成员 肯定会占用内存的.类在没有生成 对象(实例)之前不会占用 内存空间.执行 构造函数(构造方法) 就是为 对象 分配资源的一个过程.包含这个函数
public static void main( String[] args){}
的类会占用内存.
>>
类变量当然要占用内存,Java虚拟机都有一个唯一的方法区,在Java虚拟机装载类完成验证之后,Java虚拟机会为类变量分配内存保存在方法区。类常量会由java编译器特殊处理,不在方法区中。
Rectangle (tt) 是什么?
程序中如果为静态的变量和方法,内存又该怎样画?
有实例变量和静态变量的类在初始化对象之前静态变量就占内存空间了吗?
初始化对象后,每个对象对象中有实例变量的内存空间,有静态变量内存空间吗?
另外你还得记住,从汇编的角度看,数据跟执行代码(或者说函数)在不同的区域,一般我们考虑是不关执行代码所占有的内存的,不过函数的重载并不能直接翻译到汇编上去,里面还有重新命名技术,
要搞清楚他,最好就是用vc去写个类,然后再调试的时候去看如何把各种类的机制解析成汇编语言,通过看汇编语言你就会明白里面很多的问题编译器是如何解决的啦,
最后我java跟c++好像有个很大的区别,java的对象好像永远都是在堆上为对象分配内存,但是c++却也可以在栈中分配一个对象
类
1.静态成员变量
2.静态方法集
3.实例成员变量访问方法集
--------------------------------
对象1
实例成员变量
--------------------------------
对象2
实例成员变量
----------------
因为静态成员变量的存在是不需要类实例化后也可访问的.所以需要静态方法去访问。实例成员变量,也就是类在实例化后分配内存时只是为实例成员变量分配了内存和方法无关。你对
对象1.print()和对象2.print()方法调用在jvm内部应该是
类.print(对象1) 类.print(对象2)如果你的类没有实例成员变更,想用单实例和静态类在实现思想没什么不同,只是在调用方便性和OO上有点区分。
以上是我的理解。
不管创造多少对象,或者一个也没有创建,静态域总是存在。
在方法中,类的域和其他方法可以直接被命名,而不必显示指出对象引用。
this是当前对象的引用,this引用被隐式地用于一个对象的实例变量和方法。
java仅保留类每个方法的一个拷贝以节省内存,该类的每个对象都调用这个方法拷贝,另一方面,每个对象都具有类的实例变量的拷贝。
所有的静态的方法和静态变量在装入类是,就分配了内存,所有类的实例都使用共同的的静态的方法或静态域,而类中的非静态成员,只有类实例化,类中的非静态成员每实例化一次,就分配一次内存,不同实例分配的内存也各不相同。同一包中的类可以互相访问,要实现包外访问,必须声明类为public,声明为public的类成为公共类,应用于类上的访问控制符只有public,不使用任何访问控制符修饰的类,只在包中可见。