小夕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.ist2.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-descriptionincludeexclude
@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;
    }
   } 


没有评论

Blogger 提供支持.