用引用操作对象
在java中一切都被视为对象,尽管一切都看做对象,但操作的标识符实际上是对对象的一个‘引用’。举例说明:可理解为用遥控器(引用)操控电视机(对象),只有握住遥控器就可以操控电视机,当要更变频道或调节时候,实际上操作的是遥控器。除此之外。
即使没有电视机,遥控器也可以独立存在,也就是说 拥有一个引用并一定需要一个对象与它关
String s; 这里所创建的只是一个引用,并不是对象。如果此时向 s 发送一个消息,就会返回一个空指针异常。因此安全的做法是在创建引用的时候就进行初始化 String s = "asdf";
这里用了java语言一个特性:字符串可以用带引号的文本初始化。通常,必须对对象采用更通用的初始化方法。
必须由你创建所有对象
一旦创建了一个引用,就希望它能与一个对象关联,通常用new操作符来实现这一个目的。
String s = new String("asdf");
存储在什么地方
程序运行时,对象是怎么进行安置的呢?尤其是内存是怎么分配的? 有5个不同的地方可以存储数据:
1)寄存器。这是最快的储存区,因为它是位于不同于其他存储区的地方----处理器内部。但是寄存器的是数据及其有限,所以寄存器是根据需求分配的。你不能直接控制,也不能在程序中感觉到寄存器存在的任何迹象。
2)堆栈。位于通用的RAM(随机访问存储器)中,但通过堆栈指针可以从处理器哪里获得直接支持。堆栈指针向下移动,则分配新的内存;若向上移动,则释放哪些内存。这是一种快速有效的分配存储方法,仅次于寄存器。创建程序时候Java必须知道存储在堆栈内的所有项的生命周期,以便上下移动指针。这一约束限制了灵活性,所以虽然某些java数据存储于堆栈中----特别是对象引用,但是java对象并不存储其中。除此之外,基本类型也存放与堆栈中。
3)堆。一种通用的内存池(RAM区),用于存放所有的java对象。堆不同于堆栈的好处是:编译器不需要知道存储的数据在堆李存活多久,因此在堆里分配存储有很大的灵活性。需要一个对象的时候只需用new写一行简单代码,当执行这行代码时候,会自动在堆里进行存储分配。这种灵活性付出代价是用堆存储分配和清理会比用堆栈需要更多的时间。
4)常量存储。常量值通常直接放在程序内部,这样是安全的,因为他们永远不会被改变。
5)非RAM存储。如果数据存储在程序之外,那么它可以不受程序的任何影响。其中两个基本的例子是流对象和持久化对象。在流对象中,对象转化成字节流,通常发送给另一台机器。在持久化对象中,对象存在存放在磁盘。
特例:基本类型
在程序中经常使用一系列的类型,它们需要特殊对待,可以把他们想象成‘基本’类型。之所以特殊对待,是因为new将对象存放在堆中,所以用new创建一个对象---特别是小的,简单的变量,往往不是很有效。因此对于这些类型 不用new来创建变量,而是创建一个并非是引用的‘自动’变量。这个变量直接存储‘值’,并置于堆栈中,因此更有效。
简单提一下:Java SE5 引入了包装类。
对象的作用域
作用域是由花括号决定的
{
int x = 12;
}
x 在超出花括号之外是无效的
但是java对象不具备和基本类型一样的生命周期。当用new创建的对象,是可以存活于作用域之外的,比如
{
String s = new String("a string");
}
着这段代码中,引用s(堆栈中)在作用域终点就消失了,但是s所指向String对象依然继续占据着内存空间(在堆中)。我们无法在这个作用域之外访问这个对象了,因为它的唯一引用s已经超出了作用域。(后面会讲怎么传递和复制对象引用)。
这样就会带来有一个问题,在堆中占据的内存是在什么时候被释放呢?Java中有一个垃圾回收器,用来监听用new创建的所有对象,并能识别那些不会被引用的对象,发现这些不会被引用对象就会释放占用的内存空间,以便其他的新的对象使用。
参数列表
方法的参数列表指定要传递给方法什么样的信息。有一种是引用传递(有人也说引用传递其实也是值传递),有一种是值传递。大家可以看看下面这篇文章https://www.cnblogs.com/coderising/p/5697986.html
https://blog.csdn.net/morgerton/article/details/54908592
https://blog.csdn.net/zhzhao999/article/details/53449504
static 关键字
通常来说,创建类是,除非用new关键字创建类的对象,否则实际上并没有获取任何对象,执行new创建时,数据存储空间才被分配,其方法才被外界调用。
但是有两种情形上述方法是无法解决的。第一种是:只想为某特定域分配单一存储空间,而不去考虑究竟要创建多少对象,甚至根本就不用创建任何对象。另一种是:希望某个方法不与类关联在一起,也就是说不用创建类也能调用这个方法。通过statci关键字可以满足这两种需求。
静态区域块
public class Test { public static void main(String[] args) { StaticTest s1 = new StaticTest(); StaticTest s2 = new StaticTest(); } } class StaticTest{ static { System.out.println("静态区域块的代码只会执行一次"); } }
通过上面的例子我们可以kandao
在类加载的时候就会执行,仅仅执行一次。不管我们new多少个对象,面的例子
静态变量
public class Test { public static void main(String[] args) { StaticTest s1 = new StaticTest(); StaticTest s2 = new StaticTest(); s1.i = 48; System.out.println(s1.i); System.out.println(s2.i); } } class StaticTest{ static int i = 47; }
上面的例子当中,我们仅仅在s1上对StaticTest的静态变量i做了修改。但是从s2的打印结果上我们可以看到也是48,所以说明
静态变量是所有对象共享,在内存中仅有一份
静态方法
public class Test { public static void main(String[] args) { StaticTest.test(); } } class StaticTest{ public static void test(){ System.out.println("静态方法的调用可以不用通过new关键字"); } }
在本例中我们对test()的调用,没有通过去new一个StaticTest类的对象。说明static修饰的方法不依赖任何对象
好了,第二章的内容到此为止了,好像也没什么东西(扮个鬼脸) 。。。
第三章的话,就是介绍操作符了。。。
刚刚开始博客,第一感觉就是写博客真的好累啊,呵了个呵
~~~开心快乐每一天~~~