函数传参问题
基本数据类型传参 传的是常量在常量池中的地址
引用数据类型传参 传的是对象在堆内存中的地址
记住一点,实参——>形参 传的永远是地址
基本数据类型 是原子型数据 就是不可再拆分
引用数据类型 是复合型数据 当前对象数据中,其实还包括了其他更多的子数据
int a,b,c;-> arr [a,b,c]
人:姓名 年龄 性别 身高 体重....
复合型数据 指的就是由多个基本数据或其他引用数据组成的一个数据
形参变量永远不可能去改变实参中已储存的数据地址 除非return 实参且接收
就算形参变量所存储的数据地址被改变 那也是改变形参自己 与实参无关
无非是:
实参本身指向的是一个对象
然后把这个对象的地址传递给了形参
形参就可以通过该地址去堆内存中找对象,可以修改对象中的数据
实参再去访问对象时,对象中的数据就已经被改变
因为实参和形参目前使用操作的都是同一个对象!
终结总结:
无论实参还是形参 实参就是把变量空间所存的地址给了形参而已
他们都是变量!
所以对于变量的修改而言,主要分两种!
1.要么改变该变量空间所存储的地址
int a=3;
a=7;
int[] arr=new int[]{1,2,3};
arr=new int[]{3,2,1};
2.要么改变该变量空间所存储的地址所指向的那个对象中的数据
int[] arr=new int[]{1,2,3};
arr[0]=10;
对与基本数据类型而言,能否支持2操作 不能!
class Test02{
public static void main(String[] args){
int a=3;
int b=7;
swap(a,b);
System.out.printf("a=%d,b=%d\n",a,b);
int[] arr={3,7};
swap(arr[0],arr[1]);
System.out.printf("arr[0]=%d,arr[1]=%d\n",arr[0],arr[1]);
swap(arr);
System.out.printf("arr[0]=%d,arr[1]=%d\n",arr[0],arr[1]);
swap2(arr);
}
public static void swap(int m,int n){
m=7;
n=3;
}
public static void swap(int[] arr){
arr[0]=7;
arr[1]=3;
}
public static void swap2(int[] arr){//0xabc
arr=new int[]{10,20};
}
}
String [] args
主要用在当我们执行Java程序(java 字节码文件)的时候 可以指定一些参数的 输入的值最后都会到args中,只不过输入的数是以字符串的形式出现的。
args 其实并不是确定的,它也是可变的,只不过人们习惯了这样使用它而已。
可变长参数
- 当我们在给一个函数传参的时候,如果我们不确定具体传参数的个数的话,可以使用可变长参数(这些参数必须是相同的类型)
- 可变长参数本质上就是一个数组
- 注意点:
- 如果可变长参数和固定参数同时存在的,那么可变长参数必须在参数列表的最后面
- 一个参数列表当中最多只能出现一个可变长参数,如有多个可变长参数编译报错
for each 循环
本质:其实是一个简化过后的for循环。
格式:
for(循环数据类型 循环变量名 : 可迭代对象 ){
循环体;
}
使用foreach循环只是对复制过来的对象进行操作,被复制对象本身并不发生什么变化。
class Test01{
public static void main(String[] a){
System.out.println(a.length);
for(int i=0;i<a.length;i++){
System.out.println(a[i]);
}
multiArguments(1,2,3,4,5,6,7);
}
public static void multiArguments(int ... nums){
System.out.println(nums.length);
for(int num : nums){
num=1;
}
for(int num : nums){
System.out.println(num);
}
System.out.println();
}
public static void multiArguments(double ... nums){
System.out.println(nums.length);
for(int i=0;i<nums.length;i++){
System.out.print(nums[i]+" ");
}
System.out.println();
}
}
num其实表示的是nums[i] i∈[0~nums.length)
只不过在foreach中 屏蔽掉了i的具体行为
数组是可迭代对象当中的一种 并且数组可以通过角标访问
所以目前你可以认为num等效于nums[i]
但是并不代表所有的可迭代对象都有角标支持!
有些可迭代对象的元素访问顺序是比较复杂的,所以foreach就是为了避免这些复杂才出现的
foreach有什么样的一个缺点呢
它仅仅只能访问元素 不能对元素进行修改
num仅仅是nums[i]的一个备份 改num不代表改nums[i]
如果仅仅访问元素的话 foreach更简单
多返回值
Java的函数仅仅只能返回单一的值,所以一般把Java中多返回值封装到数组即可。
import java.util.Arrays;
class Test02{
public static void main(String[] args){
int[] arr={1,3,5,7,9,2,4,6,8};
Arrays.sort(arr);
System.out.println(Arrays.binarySearch(arr,8));
arr=Arrays.copyOf(arr,arr.length+1);
System.out.println(Arrays.toString(arr));
//MyArrays.sort(arr);
//传入一个坐标点,将坐标点进行移动
int x=0;
int y=0;
int[] res=move(x,y,10,10);
x=res[0];
y=res[1];
System.out.println("x="+x);
System.out.println("y="+y);
}
//如果是C/C++语言的话 只需要传x 和 y的指针即可
//void move(int *x,int *y){ *x+=deltx; *y+=delty;}
public static int[] move(int x,int y,int deltx,int delty){
x+=deltx;
y+=delty;
return new int[]{x,y};
}
}