学习内容:
1.方法的参数传递
方法的参数传递通常分为两种:值传递和引用传递。Java的传递只有值传递,因为不管用户传入的参数是基本类型还是引用类型,都是对原有值的复制
(1)传入的是基本类型
如果传入的是基本类型会在栈中分配内存,当按基本类型传递时,实参会多复制一份,因此,在方法内修改参数值时不影响原实参
1 package day01; 2 public class MethodDemo{ 3 private static int x=10; 4 public static void main(String[] args) { 5 MethodDemo demo = new MethodDemo(); 6 demo.getX(x); 7 System.out.println("x="+x); 8 } 9 public void getX(int x) { 10 x--; 11 } 12 }
x的值没有改变,因为当在方法结束之后,传入的x值会被垃圾回收,但是在方法内部确实是改变的
(2)引用类型传递
引用类型传递是在栈中声明,在堆中分配内存
1 package day01; 2 public class Demo{ 3 public static void main(String[] args) { 4 P p = new P(); 5 p.name="张无忌"; 6 p.age=30; 7 P p2=new P(); 8 p2.name="伍正云"; 9 p2.age=25; 10 p.t(); 11 p2.t(); 12 } 13 } 14 class P{ 15 String name;//姓名 16 int age;//年龄 17 public void t() { 18 System.out.println("姓名:"+name+",age"+age); 19 } 20 }
当通过 " 对象名 . 属性名 ” 实际上就是每一个对应的堆内存空间的属性。
只要存在了关键字 new ,Java就会开辟新的内存空间
每个对象中实际保存的只是属性,并没有方法,因为所有的方法都是每个对象共同拥有的,保存在全局代码区中。
栈内存保存的是对堆内存的引用地址,而堆内存中保存的是每一个对象所拥有的属性,全局代码区中保存的是所有类中的方法,表示公共调用
所谓的引用类型传递,就是一个堆内存空间,可以同时被多个栈内存所指向,类本身也是一样的,即一块堆内存可以同时被多个对象所同时指向
1 package day01; 2 public class Demo{ 3 public static void main(String[] args) { 4 P p = new P(); 5 p.name="张无忌"; 6 p.age=30; 7 P p2=p; 8 p2.name="伍正云"; 9 p2.age=20; 10 p.t(); 11 } 12 } 13 class P{ 14 String name;//姓名 15 int age;//年龄 16 public void t() { 17 System.out.println("姓名:"+name+",age:"+age); 18 } 19 }
p的属性被p2给修改了,这是因为一个堆内存空间可以同时被多个栈内存所指向,从而引发的结果
1 package day01; 2 public class Demo{ 3 public static void main(String[] args) { 4 //创建对象 5 Demo demo=new Demo(); 6 P p = new P(); 7 p.age=20; 8 //调用getX方法 9 demo.getX(p); 10 //打印p.age 11 System.out.println(p.age); 12 } 13 public void getX(P p) { 14 p.age=45; 15 } 16 } 17 class P{ 18 String name;//姓名 19 int age;//年龄 20 public void t() { 21 System.out.println("姓名:"+name+",age:"+age); 22 } 23 }
2.方法递归
所谓方法递归,是指方法调用自身,当然,递归不会无休止地调用下去,它必然有一个出口,当满足条件时程序也就结束了。
要想使用递归,必须满足以下两个条件
- 必须满足一个结束的条件
- 方法调用自身
使用递归实现 n 的阶乘:
1 package day01; 2 public class JieCheng{ 3 public static void main(String[] args) { 4 JieCheng j=new JieCheng(); 5 long i=j.f(5); 6 System.out.println(i); 7 } 8 public long f(int n) { 9 if(n==1) { //满足结束条件 10 return 1; 11 } 12 return n*f(n-1); //调用自身 13 } 14 }
注意:不要过多使用递归,否则会影响性能问题
3.类的属性
属性具体表现在两个方面:一个是成员属性,成员属性也称之为全局变量;另一个是局部变量
(1)成员属性(全局变量)
成员属性定义在类中,而在方法的外面,它的范围归整个类所共享
在全局变量中,基本类型都会有一个默认值,整型变量的默认值是0,浮点型的默认值是0.0,布尔类型的默认值是false,引用类型的默认值是null
不能直接访问或修改属性,因为这样的访问和修改是极其危险的,所以通常会对属性进行封装,使用getXXX得到属性值,使用setXXX来设置属性
1 package day01; 2 public class Person{ 3 private String name; 4 private int age; 5 public String getName() { 6 return name; 7 } 8 public void setName(String name) { 9 this.name=name; 10 } 11 public int getAge() { 12 return age; 13 } 14 public void setAge(int age) { 15 this.age=age; 16 } 17 public static void main(String[] args) { 18 Person p=new Person(); 19 p.setName("小明"); 20 p.setAge(18); 21 p.getName(); 22 p.getAge(); 23 System.out.println(p.name+","+p.age); 24 } 25 }
(2)局部变量
局部变量定义在方法内部,局部变量的作用范围到方法尾结束
遇到的问题:
堆和栈的概念不清
https://blog.csdn.net/majunzhu/article/details/90671738
明天要学习的内容:
this 关键字,变量的作用域和生存期,使用枚举