参数传值机制
Java 中,所有的参数传递都是 “值传递”,传递的是值的副本。即我们得到的是 “原参数的复印件,而不是原件”。
参数的值传递不影响参数原来的值
基本数据类型参数的传值
传递的是参数的副本,不会影响原件。
引用类型参数对象 u 的传值
传递的是值的副本,但引用类型指的是 “对象的地址” 。
因此,副本和原参数都指向了同一个地址,改变副本指向对象的值,也意味着原参数指向对象的值也发生改变。
小结:参数值传递和参数对象值传递是不一样的
基本数据类型参数的值传递,是拷贝,不会影响原来的参数。
参数对象的传递,传递过程中,值是副本,但是内存地址也会传过去,进行更新。相当于原来的参数对象地址和副本参数对象地址指向的是同一个内存地址,一个变跟着变。
例如(下文代码),传递一个实参对象进一个带有形参对象的方法里以后,两个对象都指向了同一个内存地址,一个变全都变。
代码示例:测试 Java 参数传递机制
// 测试 Java 参数传递机制
public class User4 {
int id;
String name;
String pwd;
// 定义构造方法
public User4(int id,String name){
this.id = id;
this.name = name;
}
// 测试参数传递,创建一个有形参对象的普通方法
public void testParameterTransfer01(User4 u){
u.name = "阿jun2333"; // 对象调用类属性对 name 进行重新赋值
}
// 测试参数传递,创建一个有形参对象的普通方法
public void testParameterTransfer02(User4 u){
// 创建了一个新对象 u ,所以会将新对象的地址给对象 u,会替换 u1 对象传递过来的对象内存地址
u = new User4(111,"新建对象");
// 打印当前方法内部 name 属性值,因为 u 和 u1 内存地址指向不一样,所以变量值的改变不会互相影响,
System.out.println(u.name);
}
public static void main(String[] args) {
// 创建类对象,传递的实参是赋值给了 id 和 name 类属性
User4 u1 = new User4(233,"阿junZzzz");
System.out.println(u1.name + ":这是创建对象时给类属性 name 赋予的初值:"); // 此时 u1.name 为 阿junZzzz
// 调用类,并将 u1 对象传递进去,相当于是将 u1 对象的内存地址传给了普通方法里面的 u 对象
u1.testParameterTransfer01(u1);
/*
* 打印 u1 对象在调用 testParameterTransfer01() 方法以后 name 的值
* 此时 u1.name 为 阿jun2333,因为上一步操作传递对象参数进方法以后,u 和 u1 两个对象指向了同一个内存地址
* 所以在普通方法里,执行 u.name = “阿jun2333” 赋值操作了以后,u.name = u1.name = "阿jun2333"
* */
System.out.println(u1.name + ":这是 u1 对象在调用 testParameterTransfer01() 方法以后 name 的新值"); // 此时 u1.name 为 阿jun2333
/*
* 这里传递 u1 对象去对应方法里,但是由于方法里新建了 u 对象,
* u 对象有了新的内存地址,
* 所以赋值定义时,不会指向同一个内存地址了,即 u 与 u1 对象分别指向不同的内存地址。
*/
u1.testParameterTransfer02(u1); // 结果为 新建对象
System.out.println(u1.name); // 结果为 阿jun2333
}
}
Java 包机制
简述
- Java 包机制是 Java 中管理类的重要手段。
- 开发过程中会遇到大量同名的类,通过包可以很容易解决类重名的问题,也可以实现对类的有效管理。
- 包对类的作用类似于文件夹对于文件的作用
基本使用
通过 package 实现对类的管理
- 通常是类的第一句非注释性语句。
- 包名 : 域名倒着写即可,再加上模块名,便于内部管理类。(域名倒着写,作为不同公司不同项目的标识符)
命名举例:
package cn.jungle; // 与下方这个包没有任何关系
package cn.jungle.123; // 这个与上一个 cn.jungle 没有任何关联
package cn.ajun;
package cn.ajun.233;
package.
注意点
- 写项目时都要加包,不使用默认包。
- cn.jungle 和 cn.jungle.123 这两个包没有任何关联,互相独立,只是逻辑上看起来后者是前者的一部分。
代码示例
package cn.jungle;
public class TestUser {
public static void main(String[] args) {
System.out.println("阿jun修炼手册");
}
}
主要的 JDK 默认包
- java.lang 包中所有的类都可以不用导入,直接去使用。
import 详解
简述
- 如果要使用其他对象的类,则需要使用 import 去导入,从而在本类中通过类名来调用,否则就需要书写类的完整包名和类名。
- Java 会默认导入 java.lang 包中所有的类,因此有些类我们可直接使用。
- 如果导入两个同名的类,则需要使用 包名 + 类名 来显示调用相关的类。
格式:
java.util.Date date = new java.util.Date();
代码示例:导入同名类的处理
- 导入某一个包下的所有类。会降低编译速度,但不会降低运行速度
// 测试 import 导入
import java.sql.Date;
import java.sql.SQLOutput;
// 导入该包下的所有类。会降低编译速度,但不会降低运行速度
import java.util.*; // java.util 包中也有时间:java.util.Date
public class Test {
public static void main(String[] args) {
// 这里指的是 java.sql.Date
Date now;
// java.util.Date,因为和 java.sql.Date 类同名,需要完整路径
java.util.Date now2 = new java.util.Date();
System.out.println(now2);
// java.util 包的非同名类不需要完整路径,下方指的是 Scanner 类
Scanner input = new Scanner(System.in);
}
}
静态导入
简述
静态导入(static-import)是在 JDK 1.5 新增加的功能,其作用是用于导入指定类的静态属性,这样就可直接使用静态属性。
代码示例:静态导入的使用
package cn.jungle;
// 两种静态导入方式
import static java.lang.Math.*; // 导入 Math 类的所有静态属性
import static java.lang.Math.PI; // 导入 Math 类的 PI 静态属性
// 测试静态导入
public class Test2 {
public static void main(String[] args) {
System.out.println(PI);
System.out.println(random());
}
}