2020.7.17

学习内容:

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.方法递归 

所谓方法递归,是指方法调用自身,当然,递归不会无休止地调用下去,它必然有一个出口,当满足条件时程序也就结束了。

要想使用递归,必须满足以下两个条件

  1. 必须满足一个结束的条件
  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 关键字,变量的作用域和生存期,使用枚举

原文地址:https://www.cnblogs.com/ltw222/p/13384456.html