欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  Java

Java一切都是对象

程序员文章站 2022-05-12 21:29:46
...

1、用引用操作对象

  在java中一切都被视为对象,操作对象实际上的操作对象的一个“引用”。两者之间的关系就相当于用遥控器(引用)来操作电视机(对象)。拥有一个引用,并不一定需要有一个对象与它关联,比如Sting a;只是声明了一个引用并没有关联到一个对象。

2、必须由你创建所有对象

  一但创建了一个引用,就希望与一个对象相关联,通常用new来新建一个对象(java中字符串可以用带引号的文本初始化)。

  2.1、存储位置

  (1)寄存器。最快的存储区(位于处理器内部),java中无法人为直接控制(c++/c中允许向编译器建议寄存器分配方式)。

  (2)栈。位于RAM中,栈指针向下移动分配新的内存,向上移动释放内存,速度很快,仅次于寄存器。但是创建系统时java系统必须知道存储在堆栈内所有项的确切声明周期,便于上下移动指针。这一约束限制了程序的灵活性,一些基本类型的变量和对象的引用(java对象并不在其中)被存放在栈中。

  (3)堆。一种通用内存池(位于RAM中),用于存放所有的java对象。堆不同于栈的好处是:编译器不需要知道存储的数据在堆中存活多长事件。当new一个对象时会自动在堆中分配内存进行存储。在不需要该对象时由编译器自动回收无需人为控制。当然,这种灵活性是需要付出代价的:相比于c/c++在栈中创建对象需要更多的时间。

  (4)常量存储。常量值通常直接存放在程序代码内部,因为常量值永远不会改变。

  (5)非RAM存储。数据存活于程序之外,可以不受程序的任何控制。比如流对象和持久化对象。

  2.2、特例:基本类型

  程序设计中经常用到的一系列类型,比如整数,小数,字符......这些类型被称作基本类型,被特殊对待。

  为什么要特殊对待? new是将对象存储在堆中,之前说到存在堆中的数据需要的时间更长,所以对于这些经常用到的,特别小的,简单的数据,如果存在堆中代价太大。因此java不用new来创建变量,而是创建一个并非是引用的“自动”变量。这个变量直接存值并置于栈中。基本类型所占存储空间大小是固定的。

  为了适应万物皆对象,基本类型都有一个包装器类,使得可以在堆中创建一个非基本对象用来表示对应的基本类型。

  比如:

char c='a';
Character ch=new Character(c);
或者
Character ch=new Character('a');

  java se5中的自动包装功能是的两者之间可以自动转换。

  2.3、作用域

  变量作用域:变量包括直接存值的基本类型和类的引用。只在代码段内存活。

  对象作用域:

{
    String s=new String("string");      
}//end of scope

  引用s存在栈上,在作用域终点生命终结。然而s指向的String对象继续存活在堆中。由java的垃圾回收器来判断何时回收该对象。这样做消除了大部分“内存泄露”的问题。

  2.4、方法参数

  java和c/c++不同,对于java的方法参数到底是传值还是传引用很多人搞不清楚。对于基本数据类型传递的是值,因为基本数据是直接存值在栈区。对象传递的是引用(栈区的对象引用即堆区对象的地址)。以String和StringBuilder来说明。

  下面看两个例子。

public class Test
{public static void test(String str)
        {
            str = "world"+str;
        }public static void main(String[] args)
        {
            String  str1 = new String("hello");
            test(str1);
            System.out.println(str1);
        }
}

  上面例子的输出结果还是hello,为什么呢?因为在test中对str的修改并不是在原来对象上的修改,这里就涉及到了String对象的特点,String对象创建后无法修改,上面的修改实际上是:新建一个空的StringBuilder然后调用append方法插入“world”,str,然后调用toString方法新建一个新的String对象。所以此时str的引用对象已经是全新的了,所以主函数中str1并未改变。下面再看个StringBuilder的例子。

public class test1 {    static void test(StringBuilder str){
        str.append("1234");
    }    public static void main(String[] args) {
        StringBuilder a=new StringBuilder("abc");
        test(a);
        System.out.println(a.toString());
    }
}

  上面输出结果abc1234,test中对str的修改同时也对a生效,因为str和a的引用都是指向同一个StringBuilder对象,而StringBuilder是可修改的。这里足以说明传递的是引用。

以上就是Java一切都是对象的详细内容,更多请关注其它相关文章!