《Java编程思想》第二章:一切都是对象

第二章:一切都是对象

若是咱们说另外一种不一样的语言,那么咱们就会发觉一个有些不一样的世界。java

                                                                                     ——Luduing Wittgerstein(1889-1951)编程

Java是基于C++的,Java是一种更“纯粹”的面向对象程序设计语言。数组

Java和C++都是混合/杂合型语言,杂合型语言容许多种编程风格。浏览器

C++之因此成为一种杂合型语言主要是由于它支持与C语言的向后兼容。C++是C的一个超集。安全

Java中(几乎)一切都是对象。bash

一、用引用操纵对象

每种编程语言都有本身的操纵内存中元素的方式。在Java中一切都被视为对象,所以可采用单一固定的语法。尽管一切都看作对象,可是操纵的标识符其实是对象的一个“引用”(reference)。架构

例如:建立一个String的引用:并发

String s;

但这里所建立的只是引用,并非对象。若是此时向s发送一个消息,就会返回一个运行时错误。此时s尚未与任何事物相关联。所以安全的作法是:建立一个引用的同时便进行初始化。以下:app

String s=”asdf”;

这里用到了Java语言的一个特性:字符串能够用带引号的文本初始化。编程语言

二、必须由你建立全部对象

一般用new关键字来建立一个对象,new关键字的意思是“给我一个新对象”。

前面的例子就能够写成以下:

String s = new String(“asdf”);

它不只表示“给我一个新的字符串”,并且经过提供一个初始化字符串,给出了怎样产生这个String的信息。

除了String类型,Java提供了大量过剩的线程类型。重要的是,你能够自行建立类型,这是Java程序设计中一项基本行为。

1.存储到什么地方

有五个不一样的地方能够存储数据:

寄存器:

位于处理器内部,最快的存储区,数量有限,不能直接操做,根据需求进行分配,在程序中感受不到它的存在。

堆栈:

位于通用RAM(随机访问存储器)中,经过堆栈指针分配和释放内存,速度仅次于寄存器。存放于堆栈中的全部项必须明确其生命周期,便于指针移动,控制内存。对象的引用都存储在堆栈,对象并不存储在堆栈中。

堆:

也位于RAM区,用于存放对象。编译器不须要知道存储的数据在堆里存活多长时间,当须要一个对象时,只需用new来建立便可,当执行这个代码时,会自动在堆里分配空间。用堆进行存储分配和清理可能比用堆栈进行存储分配须要更多的时间。

常量存储:

常量值不会被改变,常量自己会和其余部分隔离开,能够选择将其存放在ROM(只读存储器)中。

非RAM存储:

若是数据彻底存活于程序以外,那么它能够不受程序的任何控制,在程序没有运行时也能够存在。

例如:流对象和持久化对象。

在流对象中,对象转化成字节流,一般被发送给另外一台机器。

在持久化对象中,对象被存放于磁盘上。

这种存储的特色:把对象转化成能够存放在其余媒介上的事物,在须要时,可恢复成常规的、基于RAM的对象。

2.特例:基本类型

基本类型:不使用new来建立变量,而是建立一个并不是是引用的“自动”变量,这个变量直接存储“值”,并保存在堆栈中。

Java要肯定每种基本类型所占存储空间的大小,它们的大小不会随着机器硬件架构的变化而变化,这种不变性是Java程序更具可移植性的缘由之一。

基本数据类型 大小 最小值 最大值 包装器类型
boolean - - - Boolean
cahr 16bit Unicode0 Unicode2^16-1 Character
byte 8bit -128 +127 Byte
short 16bits -2^15 +2^15-1 Short
int 32bits -2^31 +2^15-1 Interger
long 64bits -2^63 +2^63-1 Long
float 32bits IEEE754 IEEE754 Double
double 64bits IEEE754 IEEE754 Double
void - - - Void

由此能够看出,基本类型有9种,一般只说前8种。

全部数值类型都有正负号,boolean类型所占存储空间的大小没有明确指定,仅可以取true或false两个值。

基本类型具备包装器类,做用是能够在堆中建立一个非基本类型的对象用来表示对应的基本类型。Java SE5提供了自动封箱/拆箱功能。

例如:

char c = ‘x’;
Character ch = new Character(c);
Character ch = new Character(‘x’);
Character ch = ‘x’;
char c = ch;

高精度数字

Java提供了两个用于高精度计算的类:BigInteger和BigDecimal。将全部的运算符使用方法来代替,以速度换取了精度。

BigInteger支持任意精度的整数。

BigDecimal支持任何精度的定点数。

3.Java中的数组

几乎全部的程序设计语言都支持数组。Java也支持,Java确保数组会被初始化,并且不能在他的范围以外被访问。这种范围检查基于每一个数组上少许的内存开销以及运行时的下标检查,由此换来的是安全性和高效。

当建立一个数组对象时,实际上就是建立了一个引用数组,而且会赋予默认值null,此时尚未关联对象。在使用任何引用前,必须为其指定一个对象;若是使用一个仍是null的引用,在运行时将会报错。

三、永远不须要销毁对象

程序设计中变量的生命周期是很是重要的部分,变量生命周期的混乱每每会致使大量的程序bug。

1.做用域

做用域(scope)决定了在其内定义的变量名的可见性和生命周期。在做用域里定义的变量只可用于做用域结束以前。Java中,做用域由花括号的位置决定。例如:

{
  int x = 12;
  {
    int q = 96;
  }
}

Java是一种自由格式(free-form)的语言,空格、制表符、换行都不会影响程序的执行结果。

Java中不容许下面这种方式声明变量:

{
  int x = 12;
  {
    int x = 96;
  }
}

编译器会报告变量x已经定义过,Java中认为这样会致使程序混乱。

2.对象的做用域

Java对象的生命周期和基本类型的生命周期是不同的。

当用new建立一个Java对象后,它的生命周期远大于当前做用域,当前做用域只是限制了此对象的引用的生命周期,超出了当前做用域只是没法再访问此对象,此对象仍然存活于内存中。

Java中靠垃圾回收器,来监视对象,并释放不在被引用的对象的内存空间。

因此对象的生命周期是从new开始,到垃圾回收器释放其内存时结束。对象的生命周期不是随着做用域的结束而结束。

四、建立新的数据类型:类

程序设计语言习惯用关键字class来表示类型,Java中也是使用class这个关键字来建立新类型的。例如:

class ATypeName{/* Class body goes here */}

上面已经建立好了一个类型,可使用new来建立这个对象。

ATypeName a = new ATypeName();

1.字段和方法

Java的类中设置两种类型的元素:字段(数据成员)、方法(函数)。
字段能够是任何类型的对象,能够经过其引用与其进行通讯;也能够是基本类型。
例如:

class DataOnly{
  int i;
  double d;
  boolean b;
  String s;
}

此时能够建立这个类型的对象,并能够给这个对象的字段赋值,例如:

DataOnly data = new DataOnly();
data.i =47;
data.d = 1.1;
data.b = false;
data.s = “asdf”;
//修改字段的值
data.i= 50;

基本成员默认值:

若类的某个成员是基本数据类型,及时没有进行初始化,Java也会自动赋予默认值。

boolean的默认值是false;char的默认值是’\u0000’(null);byte、short、int、long都是对应类型的0;float、double都是对应类型的0.0。

上述初始化的默认值不适用于局部变量,只能用于类的成员变量。

五、方法、参数和返回值

Java中习惯用方法这个术语来表示“作某些事情的方式”。

Java的方法决定了一个对象可以接收什么样的消息。方法的基本组成部分包括:名称、参数、返回值和方法体。形式以下:

ReturnType methodName(Argument list){
  /* Method body */
}

返回类型描述的是在调用方法以后从方法返回的值。

参数列表给出了要传给方法的信息的类型和名称。

方法名和参数列表合起来称为方法签名,能够惟一的标识出一个方法。

Java中的方法只能做为类的一部分来建立,方法只能经过对象才能被调用(static方法除外),且这个对象必须能执行这个方法调用。对象调用方法时,须要先列出对象名,紧接着是句点,而后是方法名和参数列表。例如:

objectName.methodName(arg1,arg2,arg3);

假设一个方法f(),不带参数,返回类型是int,属于a对象的类,那么调用能够以下这样:

int x = a.f();

接收返回值的变量的类型必须和返回值类型兼容。

调用方法的行为一般被称为发送消息给对象。

1.参数列表

方法的参数列表指定要传递给方法什么样的信息,这些信息采用的都是对象的形式,在参数列表中必须指定每一个被传递对象的类型及名字,这里传递的实际上也是引用,而且引用的类型必须正确。

例如:

int storage(String s){
  return s.length() * 2;
}

return关键字的用法包括两方面:首先他表明方法的结束。其次传递返回值。

若返回类型时void,return关键字的做用只是用来退出方法。若是返回值类型不是void,那么不管在何处返回,编译器都会强制返回一个正确类型的返回值。

能够这样认为:大致上程序只是一系列带有方法的对象组合,这些方法以其余对象为参数,并发送消息给其余对象。

六、构建一个Java程序

1.名字可见性

名字管理对任何程序设计语言来讲,都是一个重要的问题。

为了给一个类库生成不会与其余名字混淆的名字,Java建议反转域名,句点用来表明子目录的划分。

Java1.0和Java1.1中,扩展名com、edu、org、net等约定为大写形式。Java2中包名都是用小写了。

这种机制意味着全部的文件都可以自动存活于他们本身的名字空间内,并且同一个文件内的每一个类都有惟一的标识符。

2.运用其余构件

import指示编译器导入一个包,也就是一个类库,或者一个类。

例如:导入一个类。

improt java.util.ArrayList;

导入一个包。

improt java.util.*;

3.static关键字

static关键字能够两个情形的问题:

一种是,只想为某特定域分配单一存储空间,而不去考虑究竟要建立多少对象,甚至根本就不建立对象。

另外一种是,但愿某个方法不与包含它的类的任何对象关联在一块儿。

即便从未建立某个类的对象,也能够调用其static方法或访问其static域。

Java中也用到了类数据和类方法两个术语,表明那些数据和方法只是做为整个类,而不是类的某个特定对象而存在的。

只需将static关键字放在定义以前,就能够将字段或方法设定为static。

例如:

class StaticTest{
  static int i = 47;
}

引用static变量有两种方法:能够经过一个对象去引用;也能够经过类名直接引用。

例如:

StaticTest.i++;
StaticTest s = new StaticTest();
s.i++;

使用类名是引用static变量的首先方法,某些状况下这种方式能够为编译器进行优化提供了更好的机会。

static做用于字段时,改变了数据建立的方法,static字段对每一个类来讲都只有一份存储空间,而非static字段则是对每一个对象有一个存储空间。

定义静态方法的定义方式与静态变量相似,例如:

class Incrementable{
  static void increment(){ StaticTest.i++; }
}

静态方法的调用和静态变量的调用是同样的。

static方法的一个重要用法就是在不建立任何对象的前提下就能够调用它。这一点在main()方法上是标志性的应用。(main()方法是程序的入口)

七、你的第一个Java程序

最后,让咱们编写一个完整的程序示例:

import java.util.*;
public class HelloDate {
    public static void main(String[] args) {
        System.out.println("Hello, it's: ");
        System.out.println(new Date());
    }
}

java.lang是默认导入到每一个Java文件中的,因此它的全部类均可以被直接使用。

java.lang包里没有Date类,能够经过Java JDK文档中选择“Tree”,查询类属于哪一个类库,也但是直接使用查询功能搜索Date类,就会看到它属于java.util.Date,因此使用import

java.util.*导入类库才能使用,或者使用import java.util.Date进行导入。

System类有不少属性,out成员变量是此类的一个静态的PrintStream对象,println()方法是PrintStream类的一个方法,此方法的意思是将传入的数据打印到控制台并换行。
类的名字必须和文件名相同。若是你要建立一个独立运行的程序,那么文件中必须存在一个类与文件名相同,且这个类必须包含main()方法,main()的形式是固定的,以下:

public static void main(String[] args) {}

public关键字表此方法的权限,能够被外界调用。

mian()方法的参数是一个String对象的数组。程序中并未使用args,args是用来存储命令行参数。

1.编译和运行

要编译和运行Java程序,首先必需要有一个Java开发环境。

到Java官网下载对应平台对应版本的JDK进行安装,并配置环境变量。

在你存放HelloDate.java文件的目录下打开命令行,输入如下命令:

javac HelloDate.java

若是没有任何提示信息,代表编译经过,若是有报错信息,根据错误信息进行问题解决。

而后再输入如下命令运行程序:

java HelloDate

你就会看到程序输出的消息和当天的日期。

八、注释和嵌入式文档

Java里提供两种注释风格。

第一种风格,注释以“/*”开始,随后是注释内容,并可跨越多行,最后以“*/”结束。

两种表现形式:

/*
 * This is a comment
 * that continues
 * across lines
 */

/* This is a comment that
     continues across lines */

每行的开头有没有*号都是同样的。

第二种风格,单行注释,以“//”开头,直到句末。

例如:

//This is a one-line comment

1.注释文档

javadoc是用于提取注释的工具,它是JDK安装的一部分。它采用了Java编译器的某些技术,查找程序内的特殊注释标签。它不只解析有这些标签呢标记的信息,也将毗邻注释的类名或方法名抽取出来。

javadoc输出的是一个HTML文件,能够用Web浏览器查看。

2.语法

全部的javadoc命令都只能在“/**”注释中出现,注释结束于“*/”。

使用javadoc命令的方式有两种:嵌入HTML,或使用“文档标签”。

独立文档标签是一些以“@”字符开头的命令,且要置于注释行的最前面。

共有三种类型的注释文档,分别对应于注释位置后面的三种元素:类、域和方法。

例如:

/** A class comment */
public class Documentation1 {
    /** A field comment */
    public int i;
    /** A method comment */
    public void f() {}
}

javadoc只能为public和protected成员进行文档注释。private和包内可访问成员的注释会被忽略掉。可使用-private进行标记,能够将private成员的注释也包括在内。

3.嵌入式HTML

javadoc经过生成的HTML文档传送HTML命令对代码进行格式化。

例如:

//:object/Documentation2.java
/**
*<pre>
*System.out.println(new Date());
*/
///:~

也能够自定义格式化,例如:

//:object/Documentation3.java
/**
 * You can <em>even</em> insert a list:
 * <ol>
 * <li> Item one
 * <li> Item two
 * <li> Item three
 * </ol>
 */
///:~

以上两种形式就是嵌入式HTML。

嵌入式的HTML中不能使用标题标签,例如:<h1>或者<hr>。

全部类型的注释文档都支持嵌入式HTML。

4.一些标签示例

javadoc标签详细内容能够参考JDK文档。

1>@see:引用其余类

@see标签做用是引用其余类的标签,经过@see标签能够连接到其余文档。

例如:

/**
 * @see classname
 * @see fully-qualified-classname
 * @see fully-qualified-classname#method-name
 */

上述每种格式都会在生成的文档中加入一个具备超连接的“See Also”条目。

javadoc不会检查你所提供的超连接是否有效。

2>{@link package.class#member label}

该标签与@see极其类似,只是它用于行内,而且用“label”做为超连接文本。

/**
 * you can see {@link package.class#member label} about this class
 */

3>{@docRoot}

该标签产生到文档根目录的相对路径,用于文档树页面的显式超连接。

4>{@inheritDoc}

该标签从当前这个类的最直接的基类中继承相关文档到当前的文档注释中。

5>@version

该标签用于解释代码版本的相关信息。

格式以下:

@version version-information

使用javadoc -version命令,能够直接提取出version-information。

6>@author

该标签用于标识做者信息。可使用多个次标签用于标识多个做者的信息,可是必须连续放置。

格式以下:

@author author-information
@author author-information

使用javadoc -author命令,能够直接提取author-information。

7>@since

该标签用于标识程序代码的早期版本。

8>@param

该标签用于方法文档中,标识方法中的参数标识符,以及其释义,可使用任意个数此标签。

格式以下:

@param parameter-name description

9>@return

该标签用于方法文档,标识返回值的含义。

格式以下:

@return description

10>@throws

该标签用于方法文档,标识方法产生异常的相关信息。

格式以下:

@throws fully-qualified-class-name description

11>@deprecated

该标签用于指出一些特性的改进。

在Java SE5中,此标签已经被@Deprecated注解代替。

5.文档示例

文档注释示例以下:

//:first/HelloDate.java
import java.util.Date;
/**
 *  The first Thinking in Java example program.
 *  Displays a string and today's date.
 * @author xjd
 * @author www.xxx.com.cn
 * @version 4.0
 */
public class HelloDate {
    /**
     *  Entry point to class & application
     * @param args array of string arguments
     * @throws exceptions No exceptions thrown
     */
    public static void main(String[] args) {
        System.out.println("Hello, it's: ");
        System.out.println(new Date());
    }/* Output:(55% match)
    Hello,it's:
    Thu Jun 28 17:56:45 CST 2018
    *///:~
}

第一行是做者独特的方法,用一个“:”做为特殊几号说明这是包含原文件名的注释行。

“///:~”标志源代码清单的结束。

/*Output标签表示输出的开始部分将由这个文件生成,经过这种形式,它会自动地测试以验证其准确性。

(55% match)在向测试系统说明程序的当前运行和醒一次运行的输出存在这很大差别,55%是两次输出与其的相关性程度。

九、编码风格

Java编程语言编码约定使用“驼峰风格”,驼峰风格规定:类名的首字母要大写;若是类名由几个单词构成,那么吧他们合并在一块儿,其中每一个内部单词首字母都采用大写形式。方法、字段以及对象引用名称等,将标识符的第一个单词的首字母小写,标识符内的其余单词首字母大写。

例如:

class AllTheColorsOfTheRainbow{
    int anIntegerRepresentingColors;
    void changeTheHueOfTheColor(int newHue) {}
}

十、总结

经过本章的学习,你们已经接触至关多的关于如何编写一个简单程序的Java编程知识,对Java语言及它的一些基本思想也有了一个整体认识。

我的总结:

本章大致介绍了Java的基础知识,对面向对象编程也作了一些介绍。

上一篇:《Java编程思想》第一章:对象导论

下一篇:

相关文章
相关标签/搜索