方法参数与对象构造
方法参数
对象构造
重载
默认字段初始化
无参数构造器
显式字段初始化
参数名
调用另一个构造器
初始化块
对象析构与finalize方法
方法参数与对象构造
方法参数
一般来说,将数值传递给方法(函数)的形式一共有两种:按值调用、按引用调用。
❝按值调用:表示方法接受的是调用者提供的值。
❞
❝按引用调用:表示方法接收的是调用者提供的变量地址。
❞
需要注意的是:方法可以「修改」按引用传递的变量的值,而无法修改按值传递的变量的值。
言归正传,Java
语言总是按值调用的。即:方法所得到的是所有参数值的一个副本,也就是说方法不能修改传递给它的任何参数变量的内容。
来看个例子:假定一个方法将一个参数值扩大三倍。
public static void tripleValue(double x){
x=3*x;
}
double percent=10;
tripleValue(percent);
从方法体中可以看出,该方法将参数扩大了三倍。但其实percent还是10。
来看看执行过程:
方法调用后,X成功将percent复制了一份,此时X=10 进入方法中,X进行了重新的赋值运算。但此时X的值为30,而percent仍然为10。 方法结束后,X不再使用了。
相信学过程序设计的人都知道,常见的程序中不仅仅有值,还有引用。
上面说到,对于值类型的数据,我们在Java
中修改它显然没有持久的效果。那么对象引用呢?
来看个例子:我们将某个公司的员工的工资提高,来看看效果。
public static void tripleValue(Employee x){
x.raiseSalary(200);
}
public void raiseSalary(double x){
Salary+=Salary*x
}
var harry=new Employee();
tripleValue(harry);
执行过程大概是这样的:
X初始化为harry值的一个副本,这里是一个「对象引用」。 raiseSalary
方法应用于X这个对象引用,与此同时X与harry同时引用那个Employee对象的工资提高了。方法结束时,X不再使用,对象变量harry还在引用那个工资提高了的员工对象。
大致可以这么解释:原来的对象变量和副本都「引用了同一个对象」。
下面来总结一下方法参数的有关内容
方法不能修改基本数据类型的参数(即数值型和布尔型)。 方法可以改变对象参数的状态。(改变引用对象的属性) 方法不能让一个对象参数引用一个新对象。
对象构造
前面已经简单了解了简单的构造器,可以对象的初始状态。很幸运,Java
提供了多种编写构造器的机制,下面一一介绍这些机制。
重载
有些类含有多种构造器,比如StringBuilder
类
var messages =new StringBuilder()
和var message =new StringBUilder(“To do :\n”)
这两种方式都是正确的,这种方式叫做方法的「重载」。
如果某个类的多个方法出现了相同的名字,不同的方法参数,这便出现了方法的重载。
当然Java
中允许重载多种方法,不仅仅只有构造器方法。
方法签名
方法名以及参数类型便叫做方法的「签名」。需要注意的是:返回类型并不是方法签名的一部分
也就是说不存在两个名字相同,参数类型相同却有不同返回值类型的方法。
默认字段初始化
如果在构造器中没有显式地为字段设置初始值,那么就会被自动地赋值为默认值。
❝数值类型为0,布尔值为false、对象引用为null
❞
与此同时,字段与局部变量有着一个很明显的区别。
方法中的局部变量必须明确地初始化,但在类中,没有初始化类中的字段,将会自动初始化为默认值(0、false、null)
但是如果依赖于默认值将很大程度上影响程序的可读性,这也不是一种好的编程习惯。
无参数构造器
其实很多类都会在没有编写构造器之时,自动提供一个默认的无参构造器。
由无参构造器创建对象时,对象的状态会被设置为适当的默认值。
public Employee(){
name=“”;
salary=0;
hireDay=LOcalDate.now();
}
当然如果类中有了含有方法参数的构造器方法,但是没有书写无参的构造器方法,此时如果构造无参的对象,编译器将会报错。
因为当自己编写构造器时会覆盖自动提供的默认构造器。
这里需要注意的是:当且仅当类中没有其他任何构造器时,你才会得到一个默认无参构造器。
建议在编写类时顺带写一个无参数的构造器方法,避免后期出现的错误。
显式字段初始化
通过重载类的构造器方法,可以采用多种形式设置类的实例字段的初始状态。
可以在类定义中直接为任何字段赋值
class Employee{
private String name=“ ”;
```````
}
在执行构造器之前完成了对于名字的赋值操作,这种方法并不通用,毕竟谁都不希望该类的所有构造器将实例字段都设置为同一个值。
同时初始值不一定都是常量值,下面来看个例子:
class Employee{
private static int nextId;
private int id =assignId();
````
public static int assignId(){
int r=nextId;
nextId++;
return r;
}
``````
}
这段程序中的初始值显然不是一个常量值。
参数名
我们在编写构造器方法时通常会在参数命名上犯难,一般来说,我们喜欢用单个字母作为参数名
public Employee(String n,int s){
name=n;
salary=s;
}
这样做有一个很明显的缺点,只有阅读代码之后才能够了解到它表示的含义。
也有很多人会采用在参数变量名之前加个前缀。
但更多时候我们还是倾向于采用与实例字段同名的参数名,当然直接使用与实例变量相同的参数名显然是行不通的。这时候我们需要在实例字段之前加this
关键字,指示该字段是属于该类对象的实例字段。
如果不加this
字段来访问实例字段,参数名会直接覆盖类中的实例字段。
public Employee(String name,int salary){
this.name=name;
this.salary=salary;
}
调用另一个构造器
上面我们了解到了this
关键字能帮助我们访问类中的实例字段,当然它还有另一个用途:调用同一个类的另一个构造器
当然对于格式上也有要求,this(```)
必须出现在构造器的第一行。
下面来看个例子
public Employee(double s){
//calls Employee(String ,double)
this("Employee #"+nextId,s);
nextId++;
}
初始化块
前面已经总结了两种初始化实例字段的方式:
在构造器中设置值 在声明中设置值
其实,还有第三种,称为「初始化块」
在一个类的声明中,可以包含任意多个代码块,只要对象被构造,代码块会被立即执行
来看个例子:
public Employee{
private int id;
private String name;
private double salary;
{
id =nextId;
nextId++;
}
public Employee(String name,double salary){
this.name =name;
this.salary=salary;
}
public Employee(){
name="";
salary=0;
}
````
}
在这个例子中,无论使用哪个构造器构造对象,id字段都会在对象初始化块中初始化。并且最先运行对象初始化块。
并且执行顺序有一定的规律:一般是先执行初始化块,再执行构造器方法,最后执行普通方法,如果有静态初始化块出现,优先执行静态初始化块
对象析构与finalize方法
首先必须要声明,Java
是不支持析构器方法的,因为Java
有着自己的垃圾回收器
其次,如果对象使用了内存之外的资源,当这些资源不再使用时,将其回收和利用显得格外重要。
如果一个资源使用完毕之后需要立即关闭,那么close
方法可以完成必要的清理工作。可以在对象使用完之后调用这个方法
需要注意的是:在Java
中不要使用finalize
方法来完成清理,因为这个方法已经废弃使用了。
以上就是关于方法参数与对象构造的有关知识。
<<< 左右滑动见更多 >>>