Java对象,对象引用,参数传递

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014714713/article/details/80876800

在Java中,万物皆对象!

比如定义一个学生类

public class Student {

    private int id;
    private String name;
    private int age;

    public Student() {
        // TODO Auto-generated constructor stub
        super();
    }

    public Student(int id,String name,int age){
        super();
        this.id=id;
        this.name=name;
        this.age=age;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
    }

}

然后就可以创建一个Student对象

Student stu=new Student(1, "A", 11);

细分之后:
1. 右面的“ new Student ”,是以Student类为模板的,在堆空间里创建一个Student对象;
2. 末尾的“ (1, “A”, 11) ”代表着:在对象创建之后,立即调用Student类的构造函数,对新生成的对象进行初始化,并赋值。(如果没构造函数,Java会有一个默认的构造函数的);
3. 左面的“ Student stu ” 创建了一个Student类引用变量,即可以用来指向Student对象的对象引用;
4. “ = ” 操作符使该对象引用变量指向刚才创建的那个Student对象。

Student stu;
stu=new Student(1, "A", 11);

有两个实体:一个是对象引用变量,一个是对象本身。
在java中,都是通过引用来操纵对象的,这也是两者的区别。

对象和引用的区别:

关联性:
1. 当对象的引用变量指向对象时,两者就互相联系起来,改变引用的属性,就会改变对象的属性;
2. 如果同一个对象被多个引用变量引用的话,则这些引用变量将共同影响这个对象本身;
3. 在java中,都是通过引用来操纵对象的。

差异性:
1. 一个对象可以被不同的引用变量来操纵,同时一个引用变量也可以指向不同的对象,但是同一时刻下只能指向一个对象。
2. 从存储空间上来看,对象和引用也是相互独立的,对象一般存储在堆中,而引用存储在堆栈中(存储速度而更快)。

对于Java传参来说,Java只有一种参数传递方式:那就是按值传递,即Java中传递任何东西都是传值。如果传入的参数属于基本数据类型,将得到此基本数据类型的一份拷贝;如果是传递的参数属于引用数据类型,将得到该引用的拷贝。

基本数据类型和引用数据类型的区别

每个变量都代表一个存储值的内存位置。声明一个变量时,就是在告诉编译器这个变量可以存放什么类型的值。对基本类型变量来说,对应内存所存储的值是基本类型值。对引用类型变量来说,对应内存所存储的值是一个引用,是其所引用对象的存储地址。

eg1:基本数据类型传参

public static void TestRefOne(){

    int a=10;

    System.out.println("start: "+a);
    ChangeData(a);
    System.out.println("end: "+a);

}

private static void ChangeData(int a) {
    System.out.println("ChangeData start: "+a);
    a=99;
    System.out.println("ChangeData end: "+a);
}

结果:int型变量a在ChangeData函数外部始终未改变

start: 10
ChangeData start: 10
ChangeData end: 99
end: 10

eg2:引用数据类型传参

public static void TestRefTwo(){

    Student stu1=new Student(1, "A", 11);

    System.out.println(stu1.toString());
    ChangeStudent(stu1);
    System.out.println(stu1.toString());

}

private static void ChangeStudent(Student stu) {
    stu.setAge(22);
}

结果:ChangeStudent函数传入的参数是对Student对象的一个引用,所以在ChangeStudent函数内部通过set方法改变stu的值,将会影响到外部的stu1,因为两者都是引用同一个Student对象。

Student [id=1, name=A, age=11]
Student [id=1, name=A, age=22]

引入全局静态变量sstu

private static Student sstu=null;

public static void TestRefTwo(){

    Student stu1=new Student(1, "A", 11);

    SetStaticStudent(stu1);

    System.out.println(stu1.toString());
    ChangeStudent(stu1);
    System.out.println(stu1.toString());

    SetStaticStudent(stu1);
}

private static void SetStaticStudent(Student stu) {

    if(sstu==null){
        sstu=stu;
        System.out.println("已赋值给静态变量: "+sstu.toString());
    }
    else{
        System.out.println("使用原有的静态变量: "+sstu.toString());
    }

}

private static void ChangeStudent(Student stu) {
    stu.setAge(22);
}

结果:SetStaticStudent函数第一次将Student对象的引用赋值给sstu,外部的stu1引用变量对Student对象进行了修改,sstu获取到的Student对象也是被修改过后的Student对象。

已赋值给静态变量: Student [id=1, name=A, age=11]
Student [id=1, name=A, age=11]
Student [id=1, name=A, age=22]
使用原有的静态变量: Student [id=1, name=A, age=22]

eg3:List中的对象存放方式

public static void TestObjectRefList(){

    Student stu1=new Student(1, "A", 11);
    Student stu2=new Student(2, "S", 22);
    Student stu3=new Student(3, "D", 33);

    List<Student> stulist=new ArrayList<Student>();
    stulist.add(stu1);
    stulist.add(stu2);
    stulist.add(stu3);

    System.out.println(stulist.toString());

    ChangeStudentList(stulist);

    System.out.println(stu1.toString());
    System.out.println(stu2.toString());
    System.out.println(stu3.toString());
    System.out.println(stulist.toString());

}

private static void ChangeStudentList(List<Student> stulist) {

    for (Student student : stulist) {
        student.setAge(99);
    }

}

结果:List是中存放的对象数据,都是引用数据类型

[Student [id=1, name=A, age=11], Student [id=2, name=S, age=22], Student [id=3, name=D, age=33]]
Student [id=1, name=A, age=99]
Student [id=2, name=S, age=99]
Student [id=3, name=D, age=99]
[Student [id=1, name=A, age=99], Student [id=2, name=S, age=99], Student [id=3, name=D, age=99]]

猜你喜欢

转载自blog.csdn.net/u014714713/article/details/80876800