小夕Java修炼1——一切都是对象
02 一切都是对象
Java中,一切皆是对象,那么对象存储在哪里呢?
有5个不同的地方可以存储数据:
1) 寄存器。最快的存储区,位于处理器内部。
缺点: 数量及其有限,根据需求来分配,你不能控制;
也不能在程序中感觉到寄存器存在的任何迹象(C 和 C++ 可以建议编译器以寄存器分配的方式)
2) 堆栈。位于RAM(随机访问存储器)。 通过堆栈指针从处理器那里获得直接支持。
堆栈指针向下移动,则分配新的内存
堆栈指针向上移动,则释放内存
缺点: JVM 必须知道存储在堆栈内所有项确切的生命周期,以便上下移动堆栈指针,但是限制了程序的灵活性。对象引用 和 函数调用 存储在其中。
3) 堆。一种通用的内存池(也位于RAM区),用于存放所有的Java对象。
编译器不需要知道数据在堆里存活多长时间,所以在堆里分配存储有很大的灵活性。new 一个对象会自动在堆里进行存储分配。
缺点: 用堆进行存储分配和清理比堆栈需要更多的时间。
4) 常量存储。直接放在程序代码内部,这样做是安全的,因为它们永远不会被改变。
但是在某些嵌入式系统中,常量本身会和其它部分隔离开,所以在这种情况下, 可以选在将其存在ROM(只读存储器)中。
5)非RAM存储。在程序之外,程序没有运行,数据就可以存在。
两个例子: 流对象 和 持久化对象
流对象: 对象转化为字节流,通常发给另一台机器;
持久化对象: 对象被存放于磁盘上,即使程序终止,他们仍可以保持自己的状态。
Java 提供了轻量级持久化的支持。但是 JDBC 和 Hibernate 提供了更加复杂的对在数据库中存储和读取对象信息的支持。
Java 中每种存储类型的大小是固定的,不随硬件架构变化而变化。
数组对象
创建一个数组对象,实际是创建了一个引用数组,有自己的初始化 null 值。 少了 C++ 中的数组越界问题,但多了内存开销和运行时的 下标检查。
C/C++ 数组是直接操纵的内存块。
Java 中不能用作用域隐藏对象
C++ 中可以这样写:
{
int x = 12;
{
int x = 96; // 隐藏外部x
}
}
在Java 中会报告 x 已被定义过的错误。
对象的作用域
{
String s = new String("a string");
}// End of Scope
在出了作用域,引用消失了,但是堆中的String对象继续占据内存空间。
而在CPP 中,必须保证 对象的存活时间和 需要时间一样长,确保及时销毁。
Java 的垃圾回收器会监视所有 new 创建的对象,并辨别那些不会再被引用的对象,随后释放这些对象的内存空间。
默认初始化
java 对类的字段(数据成员)会进行初始化。
class DataOnly{
boolean a; /// default false
char b; /// '\u0000' null
byte c; /// (byte) 0
short d; /// (short) 0
int e; /// (int) 0
long f; /// 0L
float g; /// 0.0f
double h; /// 0.0d
};
但是对于局部变量不会初始化。
int x ;
如果忘记初始化,编译时错误。(C++ 只会产生警告)
方法
面向对象的程序设计可以简单归纳为:向对象发送消息, 对象是
a
, 消息是 f()
。 返回类型需要和 int
兼容。
int x = a.f();
名字可见性
Java 中使用的是Internet 域名的反。
net.mindview.utility.foibles, 句点表示一个子目录的划分。
运用其他构件
Java中消除了前向引用。
class A{
public B b = new B();
};
class B{}; // 在后面定义
Java 所有代码 必须写在类里。
static
静态数据和方法一般称为: 类数据 和 类方法。
两种用途:
1- 在某特定域分配单一存储空间,而不用考虑究竟要创建多少对象
2- 希望不用创建对象就能调用方法。
1- 指向的存储空间是一样的:
class StaticTest{
static int i = 47;
};
StaticTest st1 = new StaticTest();
StaticTest st2 = new StaticTest();
st1.i
和 st2.i
指向的是同一个存储空间。
2- 通过类名来调用
StaticTest.i++;
第一个Java程序
默认导入了一个
java.lang.*
, 因为里面用到了 System.out.println();
import java.util.* ; // Date
class Test {
public static void main(String[] args) throws Exception {
System.out.println(new Date());
System.getProperties().list(System.out); /// 打印系统信息
System.out.println(System.getProperty("user.name"));
System.out.println(System.getProperty("java.library.path"));
}
}
必须又有一个类和 文件名相同,且main() 方法如果有,则必然在此类中。
javac HelloData.java
java HelloData
工程工具
一般用build.xml 来维护文档结构,java 是用Ant 工具?
javadoc 文档
默认只能为 public(公共) 和 protected(受保护的)成员进行文档注释.
-private
标记,可以把 private 成员的注释也包括在内。
文档中可以嵌入 HTML
/*
*<pre>
*System.out.println(new Date());
*</pre>
*/
也可以添加列表
/*
* You can <em>even</em> insert a list:
*<ol>
*<li> 1</li>
*</ol>
*/
每一行开头的
**
和空格会被Javadoc丢弃。
不要插入标题标签,如
<h1>
或 <hr>
, javadoc 会自己插入标题。Javadoc 标签
Javadoc 标签是 Javadoc 认可的关键字,它定义了下面信息的类型。
Javadoc 工具认可下面的标签:
标签 | 描述 | 语法 | ||
---|---|---|---|---|
@author | 添加类的作者 | @author name-text | ||
{@code} | 不把文本转换成 HTML 标记和嵌套的 Java 标签而用代码字体展示它 | {@code text} | ||
{@docRoot} | 表示从任何生成页面到生成文档的根目录的相对路径 | {@docRoot} | ||
@deprecated | 添加一个注释暗示 API 应该不再被使用 | @deprecated deprecated-text | ||
@exception | 用类名和描述文本给生成的文档添加一个副标题 | @exception class-name description | ||
{@inheritDoc} | 从最近的可继承的类或可实现的接口继承注释 | Inherits a comment from the immediate surperclass. | ||
{@link} | 用指向特定的包,类或者一个引用类的成员名的文档的可见文本标签插入在线链接 | {@link package.class#member label} | ||
{@linkplain} | 和{@link}相同,除了链接的标签用纯文本标示而不是代码字体 | {@linkplain package.class#member label} | ||
@param | 给“参数”区域添加一个有特定参数名且后跟着特定描述的参数 | @param parameter-name description | ||
@return | 添加一个有描述文本的“Returns”区域 | @return description | ||
@see | 添加带有链接或者指向引用的文本入口的标题“See Also” | @see reference | ||
@serial | 在默认的序列化字段的文本注释中使用 | @serial field-description | include | exclude |
@serialData | 记录由 writeObject( ) 或 writeExternal( )方法所写的数据 | @serialData data-description | ||
@serialField | 记录一个 ObjectStreamField 成分 | @serialField field-name field-type field-description | ||
@since | 给生成的文档添加一个带有特定 since 文本的"Since"标题 | @since release | ||
@throws | @throw 和 @exception 标签是同义词 | @throws class-name description | ||
{@value} | 当{@value}被用在一个静态字段的文本注释中,它展示了那个常量的值 | {@value package.class#field} | ||
@version | 当 -version 选项被使用时用特定的 version w文本给生成的文本添加一个“Version”副标题 | @version version-text |
给一个例子:
/**
* <h1>Hello, World!</h1>
* The HelloWorld program implements an application that
* simply displays "Hello World!" to the standard output.
* <p>
* Giving proper comments in your program makes it more
* user friendly and it is assumed as a high quality code.
*
*
* @author Zara Ali
* @version 1.0
* @since 2014-03-31
*/
public class HelloWorld {
public static void main(String[] args) {
// Prints Hello, World! on standard output.
System.out.println("Hello World!");
}
}
再举一个例子
package javadoc;
import java.io.Serializable;
/**
* 描述人对象,拥有两个属性,分别是名字和性别。
* @see javadoc.tool.Car
* @version 1.0, 2005-04-12
* @author 陈雄华
* @since JDK1.3
*/
public class Person implements Serializable
{
/**男性,值为{@value}*/
public static final int MALE = 1;
/**女性,值为{@value}*/
public static final int FEMALE = 2;
/**名字*/
protected String name;
/**年龄*/
protected int sex;
/**
* 构造一个Person实例。设定Person的名字和性别。
*
* @param name String 名字
* @param sex int 性别,有效值是{@link #MALE 男性}和{@link #FEMALE}
* @throws PersonArgumentException
* @see javadoc.tool.Car#drive(int)
*/
public Person(String name ,int sex) throws PersonArgumentException
{
if(sex != MALE && sex != FEMALE)
throw new PersonArgumentException("参数不正确");
this.name = name;
this.sex = sex;
}
/**
* 获取性别代号。
* @return int
* @see MALE
* @see FEMALE
*/
public int getSex()
{
return sex;
}
/**
* 设置性别
* @param sex int
*/
public void setSex(int sex)
{
this.sex = sex;
}
}
Leave a Comment