2.2、对象的创建
2.2.1、实例化对象
生成一个对象的步骤:
1、定义一个类
2、声明引用变量和名称。
3、通过new关键字创建一个对象。
4、当使用new创建对象时,会调用构造函数初始化对象。
创建对象的语法:
类名 名 = new 类名();
创建对象实际上就是调用构造器,我们在使用new关键字创建对象时,就是调用该类的构造器创建这个类的实例对象。
//创建一个学生的对象
Student student = new Student();
student实际上是一个对象的引用,它保存的不是对象本身,而是对象的地址。对象中的数据保存在堆内存中,栈内存中存放的是在堆内存中的地址。所以对象也是一种引用数据类型,它的类型就是所属的类。
![image-20230129171804315](https://img-blog.csdnimg.cn/img_convert/800f559b63e0470bd23b5ced7af0152e.png)
同一个类创建的不同对象是相互独立的,在实例化时为其分配内存地址,当对象不再使用时,对象由Java虚拟机的垃圾回收处理机制回收。
![image-20210620121510059](https://img-blog.csdnimg.cn/img_convert/3f4563078b86c80a75764da2ab055a2b.png)
![image-20230128173724835](https://img-blog.csdnimg.cn/img_convert/9b4168acb5d4fdb4673ed5ada2ced367.png)
2.2.2、使用对象
对象创建后,可以通过对象访问实例变量,也能调用内部的方法(权限允许范围内的)。
-
访问实例变量(需要看有没有权限)
- 有访问权限,则直接调用:对象名.属性名
- 如果属性设置为私有,想要访问属性,可以通过设置set和get方法
程序中属性赋值的几个方式: 1、默认初始化(系统默认值):在类加载阶段 2、显式初始化:在编写时直接使用赋值符号进行赋初值 3、代码块中:在代码块中对属性进行初始化 4、构造器中:在构造方法中对属性进行初始化 5、通过对象赋值:通过对象调用属性或方法进行赋值
-
调用方法(不能调用私有的):对象名.方法名(参数);
public class Student{
//公开的,创建对象后,可以直接操作该属性
public int age;
//私有的,创建对象后,需要提供public的方法进行操作
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void say(){
System.out.println("我的名字叫:"+name);
}
}
![image-20240604175159021](https://img-blog.csdnimg.cn/img_convert/5b6b73523fa75f052f5a9acfbbb52cfb.png)
2.2.3、匿名对象
匿名对象和匿名类是相关但不完全相同的概念。这两者虽然在名称上很接近,但实际上应用的上下文和目的有所不同。
- 定义上的不同
- 匿名类关注于没有名称的类定义,主要用于实现或继承某个已有的类或接口。
- 匿名对象则是关于实例化的对象,它可以是任何类的实例,而不仅仅是匿名类。
- 使用场景
- 匿名类常用于需要扩展或定制类的行为的场景,特别是当这种行为只需要一次时。
- 匿名对象则广泛用于那些不需要再次引用对象的场景,无论这个对象来自标准类还是匿名类。
匿名对象是指创建对象的方式不涉及将其赋值给变量。匿名对象可以是任何类的对象,不仅限于匿名类。它通常用于一次性使用的场景,其中不需要后续引用对象,所以涉及到给属性赋值时,不能使用匿名对象。
//假设我们有一个Calculator类,可以进行加法运算:
class Calculator {
int add(int a, int b) {
return a + b;
}
}
public class Main {
public static void main(String[] args) {
//对象创建后不赋值给变量,而是直接调用了add方法,该对象只能使用一次
int result = new Calculator().add(5, 3);
System.out.println("Result: " + result);
}
}
使用匿名方法会简化代码提高效率,但是也会导致代码的可读性和可可维护性变低,同时匿名对象被包含在某个长生命周期对象的引用链中时,可能不容易被及时回收,所以应当谨慎使用匿名对象,特别是在写正式的、需要维护的代码时。
2.2.4、参数传递机制
参数传递机制是函数或方法调用时,如何将参数从调用者传递到被调用者、以及被调用者对这些参数的操作如何影响调用者的变量的相关规则。
一般参数有两种传递的方式:
- 按引用传递(Pass-by-Reference):在按引用传递机制中,函数或方法接收的是实际参数的引用(或内存地址)。这意味着函数内部对参数的任何修改都会直接影响到原始数据。
- 这种机制允许函数或方法直接修改调用者的变量。
- 按值传递(Pass-by-Value):将实际参数值的复制品传入方法内,而参数本身不受影响
Java是按值传递,但是它的表现和传统的又有一定的区别,在Java中无论是基本类型还是引用类型,传递的都是值的拷贝,它在处理引用类型时既允许方法通过传入的引用修改对象状态,又不允许方法改变引用本身。
-
基本类型:当传递基本类型时,方法接收参数值的副本,因此对参数的任何修改都仅限于方法范围内,不会影响到原始数据。
-
引用类型:如果形参是引用数据类型,则将实参引用数据类型变量的“地址值”传递给形参。
实际上传递的也是一个复制品,但是因为引用数据类型在栈中保存的是一个地址,所以复制品保存的也是这个地址,这就导致原本的值和复制后的值都指向堆中同一个对象,所以在复制品修改属性后,原本的对象中的值同样改变。这只是引用数据类型特性而引起的,但是参数的传递仍然是值传递。