总算来到了类与对象,来看看类与对象的总结吧
首先,要知道什么是类,属性,对象
类:是一种自定义的类型,是程序员自己定义的,就像int是系统定义好的整形一样,我们可以自定义自己所需要的类型
通过自定类型,可以表示一个具有同样特征的事物的集合
比如:cat类,表示的是所有的猫,所有的猫都有一些共同的属性
属性:每个物体或者对象能看到的或者不能看到的,
比如:猫的颜色,猫的年龄,猫的爱好
对象:则是指单个实例,在一群猫中,每只单独的猫就是一个单独的对象
创建类的说法:
1.创建一个实例化对象
2.实例化一个对象
3. 把类实例化 其实都是一个意思
都是new一个实例化对象
jdk1.8以后,方法区又从堆内存中剥离出来了,但是实现方式与之前的永久代不同,这时的方法区被叫做元空间,同时,常量池也存储在元空间
类与对象的分配机制
Person p1 = new Person(); Person p2 = p1; 则可以类比数组,p2将引用指向了p1
Java内存的结构分析
- 栈:一般用于存放基本数据类型(局部变量)
- 堆:存放对象(比如Cat cat,数组等)
- 方法区:类加载信息
- 方法和属性只会加载一次
- 调用一个方法时,会产生一个新的栈(比如:a.test,则会在栈中开辟一个新的栈)
为什么String类型的地址,改变其变量,不会对原变量值造成影响?
因为:String类型的变量值是存在方法区常量池里面的两个不同地址里面,所以不会像数组那样改变
另外String中传递的虽然是一个引用,但是当其赋值之后会将其指向另一个引用,代码如下:
public class Test0 {
public static void change(String x){
System.out.println(x);
x = "2";
System.out.println(x);
}
public static void main(String[] args){
String s = "1";
change(s);
System.out.println(s);
}
}
这里将change里面的形参改成了x,但是结果也没有发生改变,仍然是1, 2, 1
实际上change(s)是将s指向的内存地址复制了一份给x,告诉x自己通过这个地址去寻找对象,所以当x中的地址变成了"2"的时候,只是将原本指向"1"地址的x改为指向"2"地址,而其中的内容并没有发生改变,故在main方法中打印的值,不会发生改变
若是在传入一个类型变量的时候,通过new方法,又new了一个新的实例,并对其中的数据进行改变,仍然不会影响原数据,因为new的新实例已经在堆中创建了一个新的内存空间来存放new的新元素,而原来的内存空间并没有被涉及到,故原来的内存空间中的值并不会发生改变
// java 代码
class Person {
String name;
int age;
}
class A {
public void change(Person p) {
p = new Person();
p.age = 200;
p.name = "tom";
Systme.out.println("A中的p" + p.age);
}
}
public static void main(String [] args) {
Person p = new Person();
p.age = 10;
p.name = "zs";
A aa = new A();
aa.change(p);
System.out.pirntln("main中的p" + p.age);
}
此时方法A中的Person通过new方法,new出来了一个新的内存空间,并在这个空间内对age和name进行赋值,但这并不影响main中开辟的p空间,故main中的p的值,不会发生改变