JavaSE—5.内存分析

举例1:

class BirthDate(){
    private int day;
    private int month;
    private int year;

    public BirthDate(int d, int m, int y) {
        day = d; month = m; year = y;
    }

    public void setDay(int d) {
        day = d;
    }

    public void setMonth(int m) {
        month = m;
    }

    public void setYear(int y) {
        year = y;
    }

    public int getDay() {
        return day;
    }

    public int getMonth() {
        return month;
    }

    public int getYear() {
        return year;
    }

    public void display() {
        System.out.println(day + " - " + month + " - " + year);
    }

    public class Test(){
        public static void main(String[] args) {
            Test test = new Test();
            int date = 9;
            BirthDate d1 = new BirthDate(7, 7, 1970);
            BirthDate d2 = new BirthDate(1, 1, 2000);
            test.change1(date);
            test.change2(d1);
            test.change3(d2);
            System.out.println("date = " + date);
            d1.display();
            d2.display();
        }

        public void change1(int i) {
            i = 1234;
        }

        public void change2(BirthDate b) {
            b = new BirthDate(22, 2, 2004);
        }

        public void change3(BirthDate b) {
            b.setDay(22);
        }
    }
}

内存中的调用过程

  1. Test test = new Test();
    int date = 9;
    BirthDate d1 = new BirthDate(7, 7, 1970);
    BirthDate d2 = new BirthDate(1, 1, 2000);
    

​ date,d1,d2,test都是局部变量,则应该在栈内存中。

​ d1,d2,test都new了一个对象,所以new出来的对象在堆内存中。

在这里插入图片描述

  1. test.change1(date);
    
    public void change1(int i) {
    	i = 1234;
    }
    

调用change1方法的时候,change1方法有一个形参,应该给i在栈内存中分配一个空间。

在这里插入图片描述

这块空间,名字是i,值是实参的值复制给了i。

执行change1方法中的i = 1234;,i的值变成了1234.

在这里插入图片描述

当执行完change1方法后,为该方法的局部变量分配的内存空间全部消失。

在这里插入图片描述

  1. test.change2(d1);
    
    public void change2(BirthDate b) {
    	b = new BirthDate(22, 2, 2004);
    }
    

b是一个局部变量,首先在栈内存中为b分配一个空间,其内容是实参传递的内容(d1的内容)。d1的地址指向一个对象,在方法执行前,会将d1地址值复制给b,所以b可以通过该地址找到与d1同样的对象。

在这里插入图片描述

当执行b = new BirthDate(22, 2, 2004);后b新new了一个对象,堆内存为该对象分配一块空间,b的地址指向该对象。
在这里插入图片描述

当执行完change2方法后,栈内存为该方法分配的空间立刻消失,即b消失。而b指向的新对象,当垃圾收集器将它回收的时候消失。

在这里插入图片描述

  1. test.change3(d2);
    
    public void change3(BirthDate b) {
    	b.setDay(22);
    }
    

在这里插入图片描述

执行b.setDay(22);后

在这里插入图片描述

change3执行完,b内存消失
在这里插入图片描述

举例2:

class Point {
	private double x;
	private double y;
	Point(double x1, double y1) {
		x = x1;
		y = y1;
	}
	public double getX() {
		return x;
	}
	public void setX(double x) {
		this.x = x;
	}
	public double getY() {
		return y;
	}
	public void setY(double y) {
		this.y = y;
	} 
}

class Circle {
	private Point o;
	private double radius;
	Circle(Point p, double r) {
		o = p;
		radius = r;
	}
	Circle(double r){
		o = new Point(0.0, 0.0);
		radius = r;
	}
	boolean contains(Point p) {
		double x = p.getX() - o.getX();
		double y = p.getY() - o.getY();
		if(x*x + y*y > radius * radius) {
			return false;
		} else {
			return true;
		}
	}
	public void setO(double x, double y) {
		o.setX(x);
		o.setY(y);
	}
	public Point getO() {return o;}
	public double getRadius() {return radius;}
	public void setRadius(double r) {radius = r;}
	public double area() {
		return 3.14 * radius * radius;
	}
}

public class test {
	public static void main(String[] args) {
		Circle c1 = new Circle(new Point(1.0, 2.0), 2.0);
		Circle c2 = new Circle(5.0);
		System.out.println("c1:(" + c1.getO().getX() + "," + c1.getO().getY() + ")," + c1.getRadius());
		System.out.println("c2:(" + c2.getO().getX() + "," + c2.getO().getY() + ")," + c2.getRadius());
		System.out.println("c1 area = " + c1.area());
		System.out.println("c2 area = " + c2.area());	
	}
}

  1. 执行Circle c1 = new Circle(new Point(1.0, 2.0), 2.0);后的内存空间如图:
    在这里插入图片描述
    Circle c1执行时,c1是一个局部变量,存储在栈内存中,然后执行new Point(1.0, 2.0),因为new了一个Point对象,所以该Point对象存在堆内存中,并且该对象有两个成员变量,然后准备调用Point的构造方法,Point的构造方法中两个形参x1和y1是局部变量,存入栈内存中,并且给x1传值1.0,给y1传值2.0。开始执行Point的构造方法,将x1的值赋给new出来point的x,将y1的值赋给new出来point的y,所以new出来的Point对象的成员变量的值分别是1.0和2.0。构造方法结束,栈内存为该方法分配的内存空间消失,即1和2消失。

new Circle(new Point(1.0, 2.0), 2.0);执行时,准备执行Circle的构造方法,其构造方法中有p和r两个形参,所以会在栈内存中分配两个空间给p和r,而将new Point(1.0, 2.0)作为形参传递给了new Circle对象,所以可以通过p的地址找到new出来的Point对象,将2.0传递给r。开始执行new Circle();,则在堆内存中分配空间给Circle对象,Circle对象中有两个成员变量,第一个成员变量是Point对象的一个引用(o = p),o和p指向同一个引用,第二个成员变量radius,是将r的值赋给radius。所以radius的值是2.0。Circle的构造方法结束,栈内存为Circle分配的空间3和4消失。

Circle c1 = new Circle()执行,所以c1指向堆内存中的Circle对象。

  1. 执行Circle c2 = new Circle(5.0);后内存如图
    在这里插入图片描述
    ​执行Circle c2后,c2是一个局部变量,栈内存为其分配空间,其地址指向new出来的Circle对象,执行new Circle(5.0);,该对象在堆内存中,该对象有两个成员变量0和radius,然后准备执行Circle的构造方法,调用构造方法有一个形参r,所以在栈内存中为其分配空间,并且传递的值是5.0,开始执行Circle的构造方法,执行o = new Point(0.0, 0.0);,new出来的Point对象在堆内存中,且两个值为0.0,然后执行radius = r;将r的值5.0赋给radius,构造方法结束,5消失。

猜你喜欢

转载自blog.csdn.net/qq_32661327/article/details/83038574
今日推荐