基本概念
形参和实参
形式参数:在定义函数名和函数体时使用的参数,目的是用来接收调用该函数时传入的参数,简称“形参”。
实际参数:在主函数中调用一个函数时,填入的实际的参数,简称“实参”。
//这里定义的参数就是形参
void func(int arg1,String arg2)
{
}
public static void main(String[] args)
{
int a=1;
String b="hello";
//此处调用了func函数,传入的a和b就是实参
func(a,b);
}
值传递和引用传递
值传递 | 引用传递 | |
---|---|---|
传递内容 | 实参的拷贝 | 实参的地址 |
作用 | 函数对参数进行修改,不影响原来的实际参数 | 函数对参数进行修改,影响实际参数 |
java数据类型
java数据类型分为基本数据类型和引用数据类型
基本数据类型:boolean float char byte short int long double
引用数据类型,包括数组、类和接口。
基本数据类型的封装属于引用数据类型。
值传递实例
public class Test {
public static void Add(int a)
{
a=a+10;
System.out.println("函数中:");
System.out.println(a);
}
public static void main(String[] args) {
int a=10;
System.out.println("调用函数前:");
System.out.println(a);
Add(a);
System.out.println("调用函数后:");
System.out.println(a);
}
}
结果:
调用函数前:
10
函数中:
20
调用函数后:
10
引用传递实例
public static void Change(Pizzer p)
{
p.setName("b");
p.setPrice(20);
System.out.println("函数中:");
System.out.println(p.hashCode()+"|"+System.identityHashCode(p));
System.out.println("pizzer "+p.getName()+"'s price is "+p.getPrice());
}
public static void main(String[] args) {
Pizzer p=new Pizzer();
p.setName("a");
p.setPrice(10);
System.out.println("调用函数前:");
System.out.println(p.hashCode()+"|"+System.identityHashCode(p));
System.out.println("pizzer "+p.getName()+"'s price is "+p.getPrice());
Change(p);
System.out.println("调用函数后:");
System.out.println("pizzer "+p.getName()+"'s price is "+p.getPrice());
}
}
class Pizzer
{
private int price;
private String name;
public int getPrice()
{
return price;
}
public void setPrice(int value)
{
price=value;
}
public String getName()
{
return name;
}
public void setName(String value)
{
name=value;
}
@Override
public int hashCode() {
return super.hashCode();
}
}
调用函数前:
pizzer a’s price is 10
函数中:
pizzer b’s price is 20
调用函数后:
pizzer b’s price is 20
例外
这里是String类型的例子:
public class Test {
public static void Change(String a)
{
System.out.println("函数中:");
System.out.println("赋值前地址"+a.hashCode()+"|"+System.identityHashCode(a));
a="World";
System.out.println("赋值后地址"+a.hashCode()+"|"+System.identityHashCode(a));
System.out.println(a);
}
public static void main(String[] args) {
String a="Hello";
System.out.println("调用函数前:");
System.out.println("地址:"+a.hashCode()+"|"+System.identityHashCode(a));
System.out.println(a);
Change(a);
System.out.println("调用函数后:");
System.out.println(a);
}
}
输出的数字为地址空间。
调用函数前:
地址:69609650|798154996
Hello
函数中:
赋值前地址69609650|798154996
赋值后地址83766130|681842940
World
调用函数后:
Hello
可以看到,传入的是地址,但是经过赋值后,地址改变。
String类型不是基本数据类型,但是还是不会改变,查看官方文档,里面有这样的一段描述:
Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are immutable they can be shared. For example:
String str = "abc";
is equivalent to:
char data[] = {'a', 'b', 'c'}; String str = new String(data);
我个人的理解是:String的值是不会改变的,每次String xx= 赋值时相当于new了一个对象,这时我们的变量地址改变了,指向了新建的对象。如上,赋值后,a指向的是新建的变量地址,而原地址的值依旧不变。
此外,对于基本数据类型的封装类,也无法改变,例如Integer类型
public class Test {
public static void Change(Integer a)
{
System.out.println("函数中:");
System.out.println("赋值前地址"+a.hashCode()+"|"+System.identityHashCode(a));
a=20;
System.out.println("赋值后地址"+a.hashCode()+"|"+System.identityHashCode(a));
System.out.println(a);
}
public static void main(String[] args) {
Integer a=10;
System.out.println("调用函数前:");
System.out.println("地址:"+a.hashCode()+"|"+System.identityHashCode(a));
System.out.println(a);
Change(a);
System.out.println("调用函数后:");
System.out.println(a);
}
调用函数前:
地址:10|798154996
10
函数中:
赋值前地址10|798154996
赋值后地址20|681842940
20
调用函数后:
10