• Unit03


        Unit03 - 对象内存管理 、 继承的意义(上)    

    1.内存管理:由JVM来管理的
      1)堆:
        1.1)存储所有new出来的对象(包含成员变量)
        1.2)没有任何引用所指向的对象就是垃圾,
            垃圾回收器(GC)不定时清理垃圾,
            回收过程是透明的(看不到的),
            调用System.gc()建议GC尽快来回收
        1.3)成员变量的生命周期:
              创建对象时存在堆中,对象被回收时一并被回收
        1.4)内存泄露:不再使用的对象没有被及时的回收
                     建议:对象不再使用时及时将引用设置为null
      2)栈:
        2.1)用于存储正在调用中方法的所有局部变量(包括参数)
        2.2)调用方法时在栈中为该方法分配一块对应的栈帧,
            栈帧中存储的是方法中的所有局部变量(包括参数),
            方法调用结束时,栈帧被清除,局部变量一并被清除
        2.3)局部变量的生命周期:
              调方法时存在栈中,方法结束时与栈帧一起被清除
      3)方法区:
        3.1)用于存储.class字节码文件(包括方法)
        3.2)方法只有一份,
            通过this来区分具体的对象


    2.继承:
      2.1)作用:实现代码的复用,避免代码的重复
      2.2)通过extends来实现继承
      2.3)父类:所有子类所共有的属性和行为
          子类:子类所特有的属性和行为
      2.4)子继承父后,子具有: 父类的+子类的
      2.5)一个父类可以有多个子类,
          一个子类只能有一个父类----单一继承
      2.6)继承具有传递性
      2.7)java规定,构造子类之前必须先构造父类
          若子类构造中不调用父类的构造,则默认super()调用父类的无参构造
          若子类构造中调了父类的构造,则不再默认提供
          super()调用父类的构造必须位于子类构造的第一句


    3.super:指代当前对象的父类对象
      super的用法:
        1)super.成员变量名------访问父类的成员变量
        2)super.方法名()--------调用父类的方法
        3)super()---------------调用父类的构造方法


    4.向上造型:
      1)父类型的引用指向子类的对象
      2)能点出来什么,看引用的类型

    //老虎是动物
    Animal o3 = new Tiger(); //向上造型

    class Animal{ //动物类
    }
    class Tiger extends Animal{ //老虎类
    }

    JAVA内存变量:
    编译期,只检查语法是否正确
    编译错误,指的是语法错误

    运行期,JVM登场----分配内存

    变量----占用的是JVM的内存

    JAVA垃圾管理:
    没有任何引用所指向的对象
    垃圾回收器(GC),不定时到内存堆中清理垃圾
    并非看到垃圾就立刻清理

    垃圾回收过程是透明的(看不到的)
    System.gc()让内存回收尽量快一些

    内存泄露:

        没有用的内存还没有被及时的回收
             若对象不用了,及时将引用设置为null

     堆-1

    堆-2

    方法区

    程序一:

    package oo.day03;
    
    public class Cell {
        int row;
        int col;
        
        Cell(int row,int col){
            this.row = row;
            this.col = col;
        }
        
        String getCellInfo(){
            return row+","+col;
        }
        
    }
    Cell.java
    package oo.day03;
    
    public class Tetromino {
        Cell[] cells;    //格子数组,成员变量
    //    Cell[] cells=null;    //如果没有下面cells = new Cell[4];声明操作,T.java里面会报索引错误
        
        Tetromino() {
            cells = new Cell[4];        //创建格子数组对象
            
        }
        
        void drop(){
            for(int i=0;i<cells.length;i++){
                this.cells[i].row++;
            }
        }
        
        void moveLeft(){    
            for(int i=0;i<cells.length;i++){
                this.cells[i].col--;
            }
        }
        
        void moveRight(){
            for(int i=0;i<cells.length;i++){
                this.cells[i].col++;
            }
        }
        
        void print(){
            for(int i=0;i<cells.length;i++){
                String str =this.cells[i].getCellInfo();
                System.out.println(str);
            }
        }
    }
    Tetromino.java
    package oo.day03;
    
    public class T extends Tetromino {
        T(){
            this(0,0);
        }
        
        T(int row,int col){
            //super();  //调用父类的无参构造---默认参数
            cells[0] = new Cell(row,col);        //创建格子
            cells[1] = new Cell(row,col+1);
            cells[2] = new Cell(row,col+2);
            cells[3] = new Cell(row+1,col+1);
        }
    }
    T.java
    package oo.day03;
    
    public class J extends Tetromino{
        J(){
            this(0,0);
        }
        
        J(int n){
            this(n,n);
        }
        
        J(int row,int col){
            this.cells[0] = new Cell(row,col);
            this.cells[1] = new Cell(row,col+1);
            this.cells[2] = new Cell(row,col+2);
            this.cells[3] = new Cell(row+1,col+2);
        }
    }
    J.java
    package oo.day03;
    
    public class O extends Tetromino{
        O(){
            this(0,0);
        }
        
        O(int n){
            this(n,n);
        }
        
        O(int row,int col){
            this.cells[0] = new Cell(row,col);
            this.cells[1] = new Cell(row,col+1);   
            this.cells[2] = new Cell(row+1,col);
            this.cells[3] = new Cell(row+1,col+1);
        }
    }
    O.java
    package oo.day03;
    
    public class TJTest {
    
        public static void main(String[] args) {
            
    //    T t = new T(2,5);
    //    printWall(t);
            Tetromino o1 = new T(2,5);  //02.-1  向上造型
            printWall(o1);                    //传值
            
            J j = new J(1,6);            //02.-2
            printWall(j);                    //向上造型,同时传值
            
        }
        //打墙+打T型-----方法二:
    //    public static void printWall(T tt){
        public static void printWall(Tetromino tt){   //01. 向上造型
    //    public static void printWall(T tt){   //01. 向上造型
    //    public static void printWall(J tt){   //01. 向上造型
            for(int i=0;i<20;i++){                //控制行
                for(int j=0;j<10;j++){            //控制行个数0
                    boolean flag = false;        //1.假设打-
                    // i = 2   j = 5
                    for(int k=0;k<tt.cells.length;k++){                    //这里循环4次;
                        if(i==tt.cells[k].row&& j==tt.cells[k].col){    //这里只取一次正确结果,如果有else,把“-”也会打上
                            flag = true;                                        //因为有四个格子,所以循环4次,这里只取对的那次,
                            break;                                                
                        }
                    }
                    if(flag){
                        System.out.print("* ");
                    }else{
                        System.out.print("- ");
                    }
                }
                System.out.println();
            }
        
        
    /*    //打墙+打T型----方法一
        public static void printWall(T tt){
            for(int i=0;i<20;i++){
                for(int j=0;j<10;j++){
                    if(i==tt.cells[0].row&&j==tt.cells[0].col
                        ||
                        i==tt.cells[1].row&&j==tt.cells[1].col
                        ||
                        i==tt.cells[2].row&&j==tt.cells[2].col
                        ||
                        i==tt.cells[3].row&&j==tt.cells[3].col){
                        System.out.print("* ");
                    }else{
                        System.out.print("- ");
                    }
                    
                }
                System.out.println();
            }*/
        }
    
    }
    TJTest.java

    增加打印“I am a T”

    package oo.day04;
    //T型
    public class T extends Tetromino{
        T(){
            this(0,0);
        }
        T(int row,int col){
            super(); //调用父类的无参构造---默认的
            super.cells[0] = new Cell(row,col); //创建格子对象
            super.cells[1] = new Cell(row,col+1);
            super.cells[2] = new Cell(row,col+2);
            super.cells[3] = new Cell(row+1,col+1);
        }
    
        void print(){ //输出4个格子的行列号
            System.out.println("I am a T:");
            super.print(); //调用父类的print()方法
        }
    }

    程序二:(类继承的演示)

    upTypeDemo.java

    package oo.day03;
    
    public class UpTypeDemo {
        public static void main(String[] args) {
            Eoo o1 = new Eoo();
            o1.e = 1;
            o1.show();
            //o1.f = 2;  //编译错误,父类不能访问子类
            
            
            Foo o2 = new Foo();
            o2.f = 1;
            o2.test();
            o2.e = 2;    //正确,子类可以访问父类
            o2.show();    //正确,子类可以访问父类
            
            
            Eoo o3 = new Foo();    //向上造型,语法:父类名字,子类的名字;
            o3.e = 1;                //这不是造型,这是访问成员,访问东西
            o3.show();
            //o3.f = 2;        //编译错误,能点出来什么,看引用类型 
                                //o3对应的是Eoo类,所以只能使用Eoo下面的方法;
        }
    }
    
    class Eoo{                //Eoo是父类
        int e;
        void show(){}
    }
    
    class Foo extends Eoo{ //Foo是子类,继承Eoo父类
        int f;
        void test(){}
    }

     课后作业:

    1 简述JVM垃圾回收机制

    参考答案

    垃圾回收机制是Java提供的自动释放内存空间的机制。

    垃圾回收器(Garbage Collection,GC)是JVM自带的一个线程,用于回收没有被引用的对象。

    2 Java程序是否会出现内存泄露

    参考答案

    会出现内存泄漏,一般来说内存泄漏有两种情况。

    一是在堆中分配的内存,在没有将其释放掉的时候,就将所有能访问这块内存的方式都删掉;

    另一种情况则是在内存对象明明已经不需要的时候,还仍然保留着这块内存和它的访问方式(引用)。

    第一种情况,在Java中已经由于垃圾回收机制的引入,得到了很好的解决。所以,Java中的内存泄漏,主要指的是第二种情况。

    下面给出了一个简单的内存泄露的例子。在这个例子中,我们循环申请Object对象,并将所申请的对象放入一个List中,如果我们仅仅释放引用本身,那么List仍然引用该对象,所以这个对象对GC来说是不可回收的。代码如下所示:

            List list=new ArrayList(10);
            for (int i=1;i<100; i++)
            {
                Object o=new Object();
                list.add(o);
                o=null;    
            }

    此时,所有的Object对象都没有被释放,因为变量list引用这些对象。

    3 JVM如何管理内存,分成几个部分?分别有什么用途?说出下面代码的内存实现原理:

        Foo foo = new Foo();
        foo.f();

    参考答案

    JVM内存分为“堆”、“栈”和“方法区”三个区域,分别用于存储不同的数据。

    堆内存用于存储使用new关键字所创建的对象;栈内存用于存储程序运行时在方法中声明的所有的局部变量;方法区用于存放类的信息,Java程序运行时,首先会通过类装载器载入类文件的字节码信息,经过解析后将其装入方法区。类的各种信息(包括方法)都在方法区存储。

        Foo foo = new Foo();
        foo.f();

    以上代码的内存实现原理为:

    1.Foo类首先被装载到JVM的方法区,其中包括类的信息,包括方法和构造等。

    2.在栈内存中分配引用变量foo。

    3.在堆内存中按照Foo类型信息分配实例变量内存空间;然后,将栈中引用foo指向foo对象堆内存的首地址。

    4.使用引用foo调用方法,根据foo引用的类型Foo调用f方法。

  • 相关阅读:
    HDU 2767 Proving Equivalences(强连通缩点)
    HDU 3836 Equivalent Sets(强连通缩点)
    POJ 2762 Going from u to v or from v to u?(强连通+缩点+拓扑排序)
    织梦dedecms中自定义表单必填项的设置方法
    dedecms中调用隐藏栏目的方法
    去掉dedecms友情链接中的LI标签的方法
    Mysql修改端口号 织梦DedeCMS设置教程
    织梦DedeCMS文章标题自动增加长尾关键词的方法
    DEDECMS短标题标签调用与字数修改的方法
    dedecms批量替换文章中超链接的方法
  • 原文地址:https://www.cnblogs.com/tangshengwei/p/6166032.html
Copyright © 2020-2023  润新知