美文网首页
第五章:面向对象基础——类与对象进一步研究 。

第五章:面向对象基础——类与对象进一步研究 。

作者: 孤意的学习笔记 | 来源:发表于2017-09-22 17:04 被阅读0次

本章目标

  • 掌握Java中的内存划分
  • 初窥Java引用传递
  • 垃圾的产生分析

内存划分:对象创建之初

public class ClassDemo02{
    public static void main(String args[]){
        Person per = new Person() ; // 创建并实例化对象
    }
}
Person per = new Person();
  • 声明对象:Person per, 栈内存中声明,与数组一样,数组名称就保存在栈内存中,只开辟了 栈内存的对象是无法使用的,必须有其堆内存的引用才可以使用。
  • 实例化对象:new Person(),在堆中开辟空间,所有的内容都是默认值。
    • String:是一个字符串,本身是一个类,就是一个引用数据类型,则此时默认值就是null。
    • int:是一个整数,本身是一个数,所以是基本数据类型,则此时的默认值就是0。

如果进一步划分以上的代码,则可以写成如下的形式:

Person per = null ;     // 声明对象
per = new Person() ;    // 实例化对象

开发中,数据最好赋一个初值,这样操作会比较方便。

了解了其分配关系,就可以为属性赋值,并调用类中的方法。
使用格式:

  • 调用属性:对象.属性
  • 调用方法:对象.方法()
class Person{
    String name ;       // 声明姓名属性
    int age ;           // 声明年龄属性
    public void tell(){ // 取得信息
        System.out.println("姓名:" + name + ",年龄:" + age) ;
    }
};
public class ClassDemo03{
    public static void main(String args[]){
        Person per = null ;     // 声明对象
        per = new Person() ;    // 实例化对象
        per.name = "张三" ;       // 为姓名赋值
        per.age = 30 ;          // 为年龄赋值
        per.tell() ;            // 调用方法,打印信息
    }
};
输出结果:
姓名:张三,年龄:30

此时,内容显示出来后,实际上所有的操作都是要在内存中直接体现出来的。

问题
对象是保存在栈内存之中的,属性是保存在堆内存之中的,那么方法呢?
在程序中,所有方法是保存在全局代码区之中的。此区域中的内容是共享的。
注意
在使用对象的时候,对象必须被实例化之后才可以使用(实例化对象,并不单单指的是通过new关键字实现的,只要有堆内存的空间指向,则就表示实例化成功。)

如果不实例化会如何呢?

Exception in thread "main" java.lang.NullPointerException
                 at ClassDemo03 main(ClassDemo03.java:12)

此时出现了一个空指向异常。

在引用操作中,如果一个对象没有堆内存的引用,而调用了类中的属性或方法,就会出现此问题。

那么既然可以产生一个对象,能不能产生多个对象呢?
可以,只要按照操作格式完成即可。

class Person{
    String name ;       // 声明姓名属性
    int age ;           // 声明年龄属性
    public void tell(){ // 取得信息
        System.out.println("姓名:" + name + ",年龄:" + age) ;
    }
};
public class ClassDemo04{
    public static void main(String args[]){
        Person per1 = null ;        // 声明per1对象
        Person per2 = null ;        // 声明per2对象
        per1 = new Person() ;       // 实例化per1对象
        per2 = new Person() ;       // 实例化per2对象
        per1.name = "张三" ;      // 设置per1中的name属性内容
        per1.age = 30 ;             // 设置per1中的age属性内容
        per2.name = "李四" ;      // 设置per2中的name属性内容
        per2.age = 33 ;             // 设置per2中的age属性内容
        System.out.print("per1对象中的内容 --> ") ;
        per1.tell() ;               // 调用类中的方法
        System.out.print("per2对象中的内容 --> ") ;
        per2.tell() ;               // 调用类中的方法
    }
};
输出结果:
per1对象中的内容 --> 姓名:张三,年龄:30
per2对象中的内容 --> 姓名:李四,年龄:33

类是引用数据类型,那么这些是如何引用的呢?
所谓的引用数据类型,实际上就是传递的就是是堆内存的使用权,可以同时为一个堆内存空间定义多个栈内存的引用操作 。

class Person{
    String name ;       // 声明姓名属性
    int age ;           // 声明年龄属性
    public void tell(){ // 取得信息
        System.out.println("姓名:" + name + ",年龄:" + age) ;
    }
};
public class ClassDemo05{
    public static void main(String args[]){
        Person per1 = null ;        // 声明per1对象
        Person per2 = null ;        // 声明per2对象
        per1 = new Person() ;       // 只实例化per1一个对象
        per2 = per1 ;               // 把per1的堆内存空间使用权给per2
        per1.name = "张三" ;      // 设置per1中的name属性内容
        per1.age = 30 ;             // 设置per1中的age属性内容
        // 设置per2对象的内容,实际上就是设置per1对象的内容
        per2.age = 33 ;             // 设置per2中的age属性内容
        System.out.print("per1对象中的内容 --> ") ;
        per1.tell() ;               // 调用类中的方法
        System.out.print("per2对象中的内容 --> ") ;
        per2.tell() ;               // 调用类中的方法
    }
};
输出结果:
per1对象中的内容 --> 姓名:张三,年龄:33
per2对象中的内容 --> 姓名:张三,年龄:33

再看一道引用传递的程序。

class Person{
    String name ;       // 声明姓名属性
    int age ;           // 声明年龄属性
    public void tell(){ // 取得信息
        System.out.println("姓名:" + name + ",年龄:" + age) ;
    }
};
public class ClassDemo06{
    public static void main(String args[]){
        Person per1 = null ;        // 声明per1对象
        Person per2 = null ;        // 声明per2对象
        per1 = new Person() ;       // 实例化per1对象
        per2 = new Person() ;       // 实例化per2对象

        per1.name = "张三" ;      // 设置per1中的name属性内容
        per1.age = 30 ;             // 设置per1中的age属性内容
        per2.name = "李四" ;
        per2.age = 33 ;             // 设置per2中的age属性内容

        per2 = per1 ;               // 把per1的堆内存空间使用权给per2
        System.out.print("per1对象中的内容 --> ") ;
        per1.tell() ;               // 调用类中的方法
        System.out.print("per2对象中的内容 --> ") ;
        per2.tell() ;               // 调用类中的方法
    }
};
输出结果:
per1对象中的内容 --> 姓名:张三,年龄:30
per2对象中的内容 --> 姓名:张三,年龄:30

因为per2改变了指向,所以其原本的内存空间就没有任何栈的引用,则这样的内存就被称为垃圾,等待着垃圾收集机制进行回收。
GC垃圾收集机制的简称。

总结

1、掌握栈与堆内存的关系
2、对象保存在栈内存之中,而具体内容保存在堆内存之中
3、对象间的引用传递,实际上传递的就是堆内存空间的使用权
4、垃圾的产生。

相关文章

网友评论

      本文标题:第五章:面向对象基础——类与对象进一步研究 。

      本文链接:https://www.haomeiwen.com/subject/rmpxextx.html