Java学习笔记Java学习笔记

Java编程指南-Chapter4 对象和类

2018-03-29  本文已影响8人  LinnChu

Chapter4 对象和类

1.内存中的对象

在类、类级或者是在方法级中声明变量时,要为赋给变量的数据分配内存空间。对于基本类型,可以很容易计算出占用的内存空间。例如,声明一个int需要4个字节,声明一个long需要8个字节。但是计算引用变量占用的内存空间就不一样了。
程序在运行时,一些内存空间分配给了数据。这个数据在空间逻辑上分为两个部分:堆和栈。基本类型分配在栈中,Java对象则放在堆中。
声明基本类型时,栈中就会分配一些字节。声明引用变量时,栈中也会分配一些字节,但是内存不包含对象的数据,它包含的是对象在堆中的地址,换句话说就是当声明:

    Book book;

就把一些字节分配给了引用变量book。book的初始值为null,因为还没有对象赋给它。当编写一下代码时:

    Book book = new Book();

这就创建了一个Book的实例,它存储在堆中,并将这个实例的地址赋给引用变量book。

Java的引用变量就像是C++中的指针,只不过不能操作引用变量而已。在Java中,引用变量用来存取它所引用对象的成员。因此,如果Book类有公有方法review,那么就可以用下面的语法来调用这个方法:

    book.review();

一个对象可以被多个引用变量引用,例如:

    Book myBook = new Book();
    Book yourBook = myBook;

第二行代码把myBook的值复制给yourBook,结果是yourBook现在和myBook引用同一个Book对象。

另一方面,下面的代码则创建了两个不同的Book对象:

    Book myBook = new Book();
    Book yourBook = new Book();

2.Java包

如果你正在开发一个由不同部分组成的应用程序,可能会想组织好各类以便于维护。有了Java,就可以将相关的类或者功能相似的类打包到一起。例如,标准Java类组成一个包,Java核心类放到java.lang包中,所有执行输入和输出操作的类放到java.io包中,等等。

如果需要更细致地组织某个包,可以创建和前者部分名称相同的包。例如,Java类库就有java.lang.annotation和java.lang.reflect包。但是要注意共用部分名称并不会让两个包有关联。例如java.lang和java.lang.reflect包是两个不同的包。

以java开头的包名预留给核心库使用,因此不能创建以单词java开头的包。你可以对属于此类包的类进行编译,但是不能运行它们。此外,以javax开头的包是准备给核心库配套的扩展库使用的,因此也不要创建以javax打头的包。

除了对类进行组织外,打包还可以避免命名冲突。例如,两个同名的类属于不同的包,那么应用程序就可以在使用来自A公司的MathUtil类的同时,又使用来自另一家公司同名的MathUtil类。为此,根据规范,包名称应该基于逆序的域名。

因此,Sun公司的包名以com.sun开头,如果我的域名为example.com,那么我的包名称相应以com.example开头。例如,我可以把所有的applet都放到com.example.applet包中,把servlet放到com.example.sesrvlet包中。

包不是一个物理对象,因此不需要创建包。要把类放到包中,就要使用关键字package,在它后面跟着的是包名称。

    package lynn.test;
    
    public class Main {
        //  example code
    }

没有包声明的类我们说它属于缺省包。应该始终使用包,因为缺省包中的类型不能为缺省包之外的其他类型所用(除非使用称之为映射的技术)。类要是没有包,这不是什么好事。

尽管包不是物理对象,但是包名和它的类源文件的物理位置还是有关系的。包名表示一个目录结构,包名中的句点表示子文件夹。

3.传值还是传引用?

可以将基本类型变量或者引用变量传递给方法。基本类型变量是传值传递,引用变量则是传引用传递。即传递基本类型时,JVM将会把传递进来的变量复制给一个新的局部变量。如果修改了局部变量的值,则这个变化不会影响传入的基本类型变量。

如果传递的是引用变量,那局部变量就指向和传入引用变量一样的对象。如果改变方法中引用的对象,这个改变也会反映到调用代码中。如下:

    package test.test1;
    
    class Point {
        public int x;
        public int y;
    }
    
    public class Test {
        public static void increment(int x) {
            x++;
        }
        
        public static void reset(Point point) {
            point.x = 0;
            point.y = 0;
        }
        
        public static void main(String[] args) {
            int a = 9;
            increment(a);
            System.out.println(a);  //  prints 9
            Point p = new Point();
            p.x = 400;
            p.y = 600;
            increment(p.x);  
            System.out.println(p.x);//  prints 400
            reset(p);
            System.out.println(p.x);  //  prints 0
        }
    }

代码分析:

4.小结

上一篇下一篇

猜你喜欢

热点阅读