一.Java值传递
首先我们来看一串代码:
输出 10 20,而不是20 10 这是为什么呢?
有内存图可以知道,这个change方法所改变的东西最终没有写回到main之中,且他传的是具体的数据,所以还会输出原数据,就相当于change是一块独立的空间方法,他怎么操作和main完全没有关系。
再来看这一段代码:
他会输出{1,88,99,4,5}是改变之后的数据,这又是为什么,不是传不到吗?
答案是否定的,数组在传递是永远不会传递里面的数值,而是传递他数组的地址,这时候方法里拿到的是他的地址,方法直接对地址操作,结果回头同步到原数组里。所以它可以传输
再来看下一段:
这个就和上一个同理,因为操作的是地址,所以方法操作会回显
那么,我们来改一下
输出 张三 18,李四 20不变
有内存图可知,change方法里依旧是自己在做交换,并没有操作地址,没有操作值里面的name,age字样,所以输出结果不变
在改变一下:
输出李四 18,张三 20
此时的change方法里有明显的name字样,说明操作的是地址,是值,会改变原有的数据
再来看最后一道题:
输出null 42 42
首先他要输出two.x的值,而byte x并没有设置值,所以为null;
然后她以上一个创建的two为模板,只不过调用了一个fix创建了two2,此时two调用了fix方法将地址改为了tt,x的值改为了42,而two2也一样,所以是42 42
二.java构造函数
构造函数的定义
构造函数(Constructor)是Java类中一种特殊的方法,用于创建对象时初始化对象的成员变量。其特点如下:
- 方法名与类名完全相同,且没有返回值(包括 void 也不能写)。
- 不能被 static 、 final 、 abstract 等修饰符修饰。
构造函数的分类与基本使用
1. 默认构造函数
若类中未显式定义构造函数,编译器会自动生成一个无参数的默认构造函数,其作用是初始化对象但不做具体赋值。
例:
class Person {}
// 编译器自动生成默认构造函数:public Person() {
}
2. 自定义构造函数
可根据需求定义带参数的构造函数,用于在创建对象时直接为成员变量赋值,避免创建后再手动设置。
例:
class Person {String name;int age;// 自定义带参数的构造函数public Person(String n, int a) {name = n;age = a;}
}
// 使用:创建对象时直接赋值
Person p = new Person("张三", 20);
应用场景
1. 对象初始化:创建对象时一次性完成成员变量的赋值,保证对象创建后处于有效状态。
例:通过构造函数确保 Person 对象必须有 name 和 age ,避免出现未赋值的空对象。
2. 重载与灵活性:一个类可以定义多个参数不同的构造函数(重载),满足不同创建需求。
例:
class Person {String name;int age;// 无参构造public Person() {} // 带一个参数public Person(String n) { name = n; }// 带两个参数public Person(String n, int a) { name = n; age = a; }
}
// 可根据需求选择构造方式
Person p1 = new Person();
Person p2 = new Person("李四");
3. 封装与安全性:通过构造函数控制成员变量的初始化逻辑(如参数校验),避免无效值。
例:
public Person(int age) {
if (age < 0) {
throw new IllegalArgumentException("年龄不能为负数");
}
this.age = age;
}
4.核心特点
- 名称特殊:方法名必须与所在类的类名完全一致(包括大小写)。
- 无返回值:不允许声明返回类型,甚至不能写 void 。
- 自动调用:创建对象时(使用 new 关键字)会自动调用,无需手动调用。
- 默认存在:若类中未显式定义任何构造函数,编译器会自动生成一个无参数的默认构造函数;一旦定义了自定义构造函数,默认构造函数就会失效(若需使用,需手动显式定义)。
- 支持重载:一个类中可以有多个构造函数,只要参数列表(参数类型、数量、顺序)不同,即构成重载,以适应不同的初始化需求。
- 作用单一:主要用于对象创建时的初始化操作(如给成员变量赋值、参数校验等),不能像普通方法一样被多次调用。
简言之,构造函数是对象创建的“初始化工具”,通过它可以规范对象的创建过程,提高代码的安全性和简洁性。
总结:
Java构造函数
构造函数是类中用于初始化对象的特殊方法,核心特点和作用如下:
1. 定义特征
- 方法名与类名完全一致,无返回值(包括 void )。
- 不能被 static 、 final 等修饰符修饰。
2. 核心作用
- 创建对象时自动调用,用于初始化成员变量(如 new Person("张三", 20) )。
- 若未显式定义,编译器会生成无参默认构造函数;若自定义了构造函数,默认构造函数需手动添加。
3. 关键特性
- 支持重载(参数列表不同),满足不同初始化需求。
- 仅在对象创建时执行一次,无法像普通方法那样被多次调用。
Java值传递
Java中方法参数的传递方式只有“值传递”,即传递的是参数的副本,而非原变量本身:
1. 定义
- 当参数为基本类型(如 int 、 char )时,传递的是具体数值的副本,修改形参不会影响实参。
例:
void change(int num) {num = 100;}
int a = 10;change(a); // a仍为10(形参修改不影响实参)
- 当参数为引用类型(如对象、数组)时,传递的是对象地址的副本,通过副本修改对象内部属性会影响原对象,但修改引用本身(如指向新对象)不会影响原引用。
例:
class Person {
int age;
}
void changeAge(Person p) {
p.age = 20;
} // 修改内部属性,影响原对象
void changeRef(Person p) {
p = new Person();
} // 修改引用,不影响原对象
带实际变量名的就会传递
2. 本质
- 无论参数类型如何,传递的都是“值的副本”:基本类型传数值副本,引用类型传地址副本。
总结
- 构造函数是对象初始化的“专属工具”,确保对象创建时处于有效状态;
- 值传递是Java参数传递的唯一方式,核心是“传递副本,不直接操作原变量”。