一切都是对象
尽管Java是基于C++的,但是相比较之下,Java是一种更“纯粹”的面向对象程序设计语言。
用引用操作对象
每种编程语言都有属于自己的操作内存中元素的方式,例如C/C++是利用指针来操作对象,而Java是利用引用来操作对象的。
String str = new String("123");
其中的str表示为引用,我们可以将引用和数据的关系理解为遥控器和电视的关系,我们可以通过遥控器对电视进行各种操作,同样的,在这里我们可以通过str对内存中的数据进行操作。要注意的是,引用和被引用的对象是两个独立的整体,就像即使电视机不存在了,遥控器也依然存在的道理,因此,我们可以不将引用指向某个对象,如下代码所示:
String str1;
这里创建的只是引用,而不是对象,如果此时向str1发送消息,就会返回运行时错误,这是因为str1实际上并没有与任何事物相关联。
必须由你创建所有对象
一旦创建了一个引用,我们就希望它能与一个新的对象相关联。通常用new操作符来实现这一目的。new关键字的意思是“给我一个新对象。”所以前面的例子可以写成:
String str = new String("123");
存储到什么地方
-
寄存器
这是最快的存储区,因为它位于不同于其他存储区的地方一一处理器内部。但是寄存器的数量极其有限,所以寄存器根据需求进行分配。你不能直接控制,也不能在程序中感觉到寄存器存在的任何迹象(另ー方面,C和C++允许您向编译器建议寄存器的分配方式)。
-
堆栈
位于通用RAM(随机访问存储器)中,但通过堆栈指针可以从处理器那里获得直接支持。堆栈指针若向下移动,则分配新的内存;若向上移动,则释放那些内存。这是一种快速有效的分配存储方法,仅次于寄存器。创建程序时,Java系统必须知道存储在堆栈内所有项的确切生命周期,以便上下移动堆栈指针。这一约束限制了程序的灵活性,所以虽然某些Java数据存储于堆中一特别是对象引用,但是Java对象并不存储于其中。
-
堆
一种通用的内存池(也位于RAM区),用于存放所有的Java对象。堆不同于堆的好处是:编译器不需要知道存储的数据在堆里存活多长时间。因此,在堆里分配存储有很大的灵活性。当需要一个对象时,只需用new写一行简单的代码,当执行这行代码时,会自动在堆里进行存储分配。当然,为这种灵活性必须要付出相应的代价:用堆进行存储分配和清理可能比用堆梭进行存储分配需要更多的时间(如果确实可以在Java中像在C++中一样在栈中创建对象)。
-
常量存储
常量值通常直接存放在程序代码内部,这样做是安全的,因为它们永远不会被改变。有时,在嵌入式系统中,常量本身会和其他部分隔离开,所以在这种情况下,可以选择将其存放在ROM(只读存储器)中。
-
非RAM存储
如果数据完全存活于程序之外,那么它可以不受程序的任何控制,在程序没有运行时也可以存在。其中两个基本的例子是流对象和持久化对象。在流对象中,对象转化成字节流,通常被发送给另一台机器。在“持久化对象”中,对象被存放于磁盘上,因此,即使程序终止,它们仍可以保持自己的状态。这种存储方式的技巧在于:把对象转化成可以存放在其他媒介上的事物,在需要时,可恢复成常规的、基于RAM的对象。Java提供了对轻量级持久化的支持,而诸如JDBC和 Hibernate这样的机制提供了更加复杂的对在数据库中存储和读取对象信息的支持。
特例:基本数据类型
在程序设计中经常用到一系列类型,它们需要特殊对待。可以把它们想像成“基本”类型。之所以特殊对待,是因为new将对象存储在“堆”里,故用new创建一个对象一特别是小的、简单的变量,往往不是很有效。因此,对于这些类型,Java采取与C和C++相同的方法。也就是说,不用new来创建变量,而是创建一个并非是引用的“自动”变量。这个变量直接存储“值",并置于堆栈中,因此更加高效。
高精度数字
BigInteger :支持任意精度的整数。也就是说,在运算中,可以准确地表示任何大小的整数值,而不会丢失任何信息。
BigDecimal :支持任何精度的定点数,例如,可以用它进行精确的货币计算。
堆和栈的区别
-
栈(stack)与堆(heap)都是Java用来在RAM中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。
-
栈的优势是:存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据可以共享,详见第3点。
堆的优势是:可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。 -
Java中的数据类型有两种。
一种是基本类型(primitive types), 共有8种,即int, short, long, byte, float, double, boolean, char(注意,并没有string的基本类型)。这种类型的定义是通过诸如int a = 3; long b = 255L;的形式来定义的,称为自动变量。值得注意的是,自动变量存的是字面值,不是类的实例,即不是类的引用,这里并没有类的存在。如int a = 3; 这里的a是一个指向int类型的引用,指向3这个字面值。这些字面值的数据,由于大小可知,生存期可知(这些字面值固定定义在某个程序块里面,程序块退出后,字段值就消失了),出于追求速度的原因,就存在于栈中。
另外,栈有一个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义
int a = 3;
int b = 3;
编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,没找到,就开辟一个存放3这个字面值的地址,然后将a指向3的地址。接着处理int b = 3;在创建完b的引用变量后,由于在栈中已经有3这个字面值,便将b直接指向3的地址。这样,就出现了a与b同时均指向3的情况。
特别注意的是,这种字面值的引用与类对象的引用不同。假定两个类对象的引用同时指向一个对象,如果一个对象引用变量修改了这个对象的内部状态,那么另一个对象引用变量也即刻反映出这个变化。相反,通过字面值的引用来修改其值,不会导致另一个指向此字面值的引用的值也跟着改变的情况。如上例,我们定义完a与 b的值后,再令a=4;那么,b不会等于4,还是等于3。在编译器内部,遇到a=4;时,它就会重新搜索栈中是否有4的字面值,如果没有,重新开辟地址存放4的值;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。
另一种是包装类数据,如Integer, String, Double等将相应的基本数据类型包装起来的类。这些类数据全部存在于堆中,Java用new()语句来显示地告诉编译器,在运行时才根据需要动态创建,因此比较灵活,但缺点是要占用更多的时间。
4.每个JVM的线程都有自己的私有的栈空间,随线程创建而创建,java的stack存放的是frames ,java的stack和c的不同,只是存放本地变量,返回值和调用方法,不允许直接push和pop frames ,因为frames 可能是有heap分配的,所以java的stack分配的内存不需要是连续的。java的heap是所有线程共享的,堆存放所有 runtime data ,里面是所有的对象实例和数组,heap是JVM启动时创建。5.String是一个特殊的包装类数据。即可以用String str = new String(“abc”);的形式来创建,也可以用String str = “abc”;的形式来创建(作为对比,在JDK 5.0之前,你从未见过Integer i = 3;的表达式,因为类与字面值是不能通用的,除了String。而在JDK 5.0中,这种表达式是可以的!因为编译器在后台进行Integer i = new Integer(3)的转换)。前者是规范的类的创建过程,即在Java中,一切都是对象,而对象是类的实例,全部通过new()的形式来创建。Java 中的有些类,如DateFormat类,可以通过该类的getInstance()方法来返回一个新创建的类,似乎违反了此原则。其实不然。该类运用了单例模式来返回类的实例,只不过这个实例是在该类内部通过new()来创建的,而getInstance()向外部隐藏了此细节。那为什么在String str = “abc”;中,并没有通过new()来创建实例,是不是违反了上述原则?其实没有。
永远不要销毁对象
作用域
大多数语言都有**作用域(scope)**的概念,它决定了在其内定义的变量名的可见性和生命周期。
对象的作用域
Java对象不具备和基本类型一样的生命周期。当用new创建一个Java对象时,它可以存活于作用域之外。
创建新的数据类型:类
字段和方法
一旦定义了一个类(在Java中你所做的全部工作就是定义类,产生那些类的对象,以及发送消息给这些对象),就乐意这种类中设置两种类型的元素:字段(有时被称为数据成员)和方法(有时被称为成员函数)。字段可以是任何类型的对象,可以通过其引用与其进行通信,也可以是基本类型中的一种。如果字段是对某个对象的引用,那么必须初始化该引用,以便使其与一个实际的对象相关联。
如下是一个具有某些字段的类:
class DataOnly{
int i;
double d;
boolean b;
}
我们可以创建一个它的对象,并且给它的字段赋值.
DataOnly data = new DataOnly();
data.i = 12;
data.d = 1.2;
data.b = false;
基本成员默认值
如果某个成员是基本数据类型,即使没有进行初始化,Java也会确保它获得一个默认值,如下图所示:
当变量作为类的成员使用时,Java才会确保给定其默认值,以确保哪些是基本类型的成员变量得到初始化,防止程序错误(C++没有此功能)。
但是,以上确保初始化的办法并不适用于局部变量。如果在局部变量中有这样一段代码:
int x;
那么得到的x值有可能是任意值(与C和C++一样),所以在使用x前,我们应该对其赋一个适当的值。
你的第一个Java程序
System有许多其他的方法可以创造很多有趣的效果(在这里就省略hello world的编写),例如:
System.getProperties().list(System.out); // 获取系统中的所有“属性”
System.out.println(System.getProperty("user.name"));
System.out.println(
System.getProperty("java.library.path")
);
main()的第一行将显示从运行程序的系统中获取的所有“属性”,因此它可以向你提供环境信息。 list()方法将结果发送给它的参数: System.out。你可以把结果发送到任何地方,例如发送到文件中。你还可以询问具体的属性,例如在本例中,我们査询了用户名和java.library.path(在程序开头和结尾处不同寻常的注释将在稍后进行解释。)
编译运行获得程序:
-- listing properties --
java.runtime.name=Java(TM) SE Runtime Environment
sun.boot.library.path=D:\IDEA\JDK\jre\bin
java.vm.version=25.152-b16
java.vm.vendor=Oracle Corporation
java.vendor.url=http://java.oracle.com/
path.separator=;
java.vm.name=Java HotSpot(TM) 64-Bit Server VM
file.encoding.pkg=sun.io
user.script=
user.country=CN
sun.java.launcher=SUN_STANDARD
sun.os.patch.level=
java.vm.specification.name=Java Virtual Machine Specification
user.dir=E:\学习呗\Java\Java编程思想\Java编程思想
java.runtime.version=1.8.0_152-b16
java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment
java.endorsed.dirs=D:\IDEA\JDK\jre\lib\endorsed
os.arch=amd64
java.io.tmpdir=D:\Temp\
line.separator=
java.vm.specification.vendor=Oracle Corporation
user.variant=
os.name=Windows 10
sun.jnu.encoding=GBK
java.library.path=D:\IDEA\JDK\bin;C:\Windows\Sun\Java\b...
java.specification.name=Java Platform API Specification
java.class.version=52.0
sun.management.compiler=HotSpot 64-Bit Tiered Compilers
os.version=10.0
user.home=C:\Users\Administrator
user.timezone=
java.awt.printerjob=sun.awt.windows.WPrinterJob
file.encoding=UTF-8
java.specification.version=1.8
user.name=pickTang
java.class.path=D:\IDEA\JDK\jre\lib\charsets.jar;D:\I...
java.vm.specification.version=1.8
sun.arch.data.model=64
java.home=D:\IDEA\JDK\jre
sun.java.command=ShowProperties
java.specification.vendor=Oracle Corporation
user.language=zh
awt.toolkit=sun.awt.windows.WToolkit
java.vm.info=mixed mode
java.version=1.8.0_152
java.ext.dirs=D:\IDEA\JDK\jre\lib\ext;C:\Windows\Su...
sun.boot.class.path=D:\IDEA\JDK\jre\lib\resources.jar;D:\...
java.vendor=Oracle Corporation
file.separator=\
java.vendor.url.bug=http://bugreport.sun.com/bugreport/
sun.cpu.endian=little
sun.io.unicode.encoding=UnicodeLittle
sun.desktop=windows
sun.cpu.isalist=amd64
pickTang // 用户名
/**以下是java.library.path**/
D:\IDEA\JDK\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;D:\IDEA\JDK\bin;C:\ProgramData\Oracle\Java\javapath;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\bin;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\libnvvp;D:\Anaconda;D:\Anaconda\Library\mingw-w64\bin;D:\Anaconda\Library\usr\bin;D:\Anaconda\Library\bin;D:\Anaconda\Scripts;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;D:\Anaconda\condabin;D:\ming64\mingw64\mingw64\bin;D:\matlab\runtime\win64;D:\matlab\bin;D:\matlab\polyspace\bin;D:\Git\Git\cmd;D:\Nodejs\;D:\Nodejs\node_global;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\cuda\bin;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\lib\x64;C:\Program Files\NVIDIA Corporation\NVIDIA NvDLISR;D:\Git\Git\usr\bin;C:\ProgramData\chocolatey\bin;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\MySQL\MySQL Server 8.0\bin;D:\Tomcat\apache-tomcat-8.5.65\bin;D:\Tomcat\apache-tomcat-8.5.65\lib;D:\maven\apache-maven-3.5.4\bin;C:\Program Files (x86)\dotnet\;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;C:\Users\Administrator\AppData\Roaming\npm;D:\pycharm\PyCharm 2020.1\bin;D:\vscode\Microsoft VS Code\bin;D:\IDEA\IntelliJ IDEA 2020.1.1\bin;D:\openVPN\bin;.
注释和嵌入式文档
Javadoc的基本语法
所有 javadoc命令都只能在注释中出现,和通常一样,注释结束于使用 javadoc的方式主要有两种:嵌入HTML,或使用“文档标签”。独立文档标签是一些以“@”字符开头的命令,且要置于注释行的最前面(但是不算前导“*”之后的最前面)。而“行内文档标签”则可以出现在 javadoc注释中的任何地方,它们也是以“@”字符开头,但要括在花括号内。共有三种类型的注释文档,分别对应于注释位置后面的三种元素:类、域和方法。也就是说,类注释正好位于类定义之前;域注释正好位于域定义之前,而方法注释也正好位于方法定义的前面。如下面这个简单的例子:
//: object/Documentation1.java
/** A class comment*/
public class Documentation1 {
/** A field comment*/
public int i;
/** A method comment*/
public void f(){};
} ///:~
注意,Javadoc只能为public和protected成员进行文档注释。private和包内可访问成员的注释会被忽略,所以输出的结果中看不到它们。
上述的代码会输出一个HTML文件,它与其他Java文档具有相同的标准格式 。
一些标签示例
@see :引用其他类
@see标签允许用户引用其他类的文档。Javadoc会在其生成的HTML文件中,通过@see标签连接到其他文档,格式如下
@see classname
@see fully-qualified-classname
@see fully-qualified-classname#method-name
上述每种格式都会在生成的文档中加入一个具有超链接的条目,但是javadoc不会检查你所提供的超链接是否有效。
{@link package.class#member label}
该标签与@see及其相似,只是它用于行内,并且是用“label”作为超链接文本而不用“See Also”
{@docRoot}
该标签产生到文档根目录的相对路径,用于文档书页面的显示连接
{@inheritDoc}
该标签从当前这个类的最直接的基类中继承相关文档到当前的文档注释中。
@version
该标签格式如下:
@version version-information
其中,“ version-information”可以是任何你认为适合包含在版本说明中的重要信息。如果javadoc命令行使用了“- version”标记,那么就从生成的HTML文档中特别提取出版本信息。
@author
该标签格式如下:
@author author-information
其中, author-information一看便知是你的姓名,但是也可以包括电子邮件地址或者其他任何适宜的信息。如果 javadoc命令行使用了- authora标记,那么就从生成的HTML文档中特别提取作者信息。
可以使用多个标签,以便列出所有作者,但是它们必须连续放置。全部作者信息会合并到同一段落,置于生成的HTML中。
@since
该标签允许你指定程序代码最早使用的版本,可以在 HTML Java文档中看到它被用来指定所用的JDK版本的情况。
@param
该标签用于方法文档中,形式如下:
param parameter-name description
其中, parameter-name是方法的参数列表中的标识符, description是可延续数行的文本,终止于新的文档标签出现之前。可以使用任意多个这种标签,大约每个参数都有一个这样的标签。
@return
该标签用于方法文档,格式如下:
ereturn description
其中,“ description”用来描述返回值的含义,可以延续数行。
@throws
“异常”。简言之,它们是由于某个方法调用失败而“抛出”的对象。尽管在调用一个方法时;只出现一个异常对象,但是某个特殊方法可能会产生任意多个不同类型的
异常,所有这些异常都需要进行说明。所以,异常标签的格式如下:
throws fully-qualifled-class-name description
其中fully-qualifled-class-name给出一个异常类的无歧义的名字,而该异常类在别处定义。description(同样可以延续数行)告诉你为什么此特殊类型的异常会在方法调用中出现。
@deprecated
该标签用于指出一些旧特性已由改进的新特性所取代,建议用户不要再使用这些旧特性,因为在不久的将来它们很可能会被删除。如果使用一个标记为@ deprecated的方法,则会引起编译器发布警告。
在 Java SE5中, Javadoc标签@ deprecated已经被@ Deprecated注解所替代。
文档示例 :
public class HelloDate {
/** Entry point to class & application
*
* @param args array of string arguments
* @throws exception 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:
Fri Jul 09 00:02:09 CST 2021
*///:~
}
}
Output标签表示输出的开始部分将由这个文件生成,通过这种形式,它会被自动地测试以验证其准确性。在本例中,(55% match)在向测试系统说明程序的每一次运行和下一次运行的输出存在着很大的差异,因此它们与这里列出的输出预期只有55%的相关性。本书中能够产生输出的大部分示例都包含这种注释方式的输出,因此你可以查看它们的运行输出,并知晓其正确性。
练习
练习1:创建一个类,它包含一个int域和一个char域,它们都没有被初始化,将它们的值打印出来,以验证Java执行了默认初始化。
public class PrimitiveTest {
static int i; // int域
static char j; // char 域
public static void main(String[] args) {
System.out.println("int i = "+i);
System.out.println("char j = " + j);
}
}
输出结果为:
int i = 0
char j =
练习2:输出hello world
练习3:(1)找出含有 Atypenamef的代码段,将其改写成完整的程序,然后编译、运行。
public class ATNTTest {
public static void main(String[] args) {
class ATypeName{
int i;
double d;
boolean b;
void show(){
System.out.println("i = "+i);
System.out.println("d = "+d);
System.out.println("b = "+b);
}
}
ATypeName aTypeName = new ATypeName();
aTypeName.i = 11;
aTypeName.d = 12.3;
aTypeName.b = true;
aTypeName.show();
}
}
输出结果为:
i = 11
d = 12.3
b = true
练习4:(1)将 Dataonly代码段改写成一个程序,然后编译、运行。
public class DataOnlyTest {
public static void main(String[] args) {
class DataOnly{
int i;
double d;
boolean b;
void show() {
System.out.println(i);
System.out.println(d);
System.out.println(b);
}
}
DataOnly data = new DataOnly();
data.i = 3;
data.d = 2.71828;
data.b = false;
data.show();
}
}
3
2.71828
false
练习5:(1)修改前一个练习,将 Dataonly中的数据在 main()方法中赋值并打印出来。同练习3
练习6:(2)编写一个程序,让它含有本章所定义的 Storage方法的代码段,并调用之。
public class StorageTest {
public static void main(String[] args) {
class StoreStuff{
int storage(String s){
return s.length()*2;
}
}
StoreStuff storeStuff = new StoreStuff();
System.out.println(storeStuff.storage("hello."));
}
}
12
练习7:(1)将 Incrementablef的代码段改写成一个完整的可运行程序。
class StaticTest{
static int i = 47;
}
class Incrementable{
static void increment(){
StaticTest.i++;
}
}
public class IncrementablefTest {
public static void main(String[] args) {
System.out.println("StaticTest.i = "+StaticTest.i);
StaticTest st1 = new StaticTest();
StaticTest st2 = new StaticTest();
System.out.println("st1.i = "+st1.i);
System.out.println("st2.i = "+st2.i);
Incrementable sf = new Incrementable();
sf.increment();
System.out.println("After sf.increment called:");
System.out.println("st1.i = "+st1.i);
System.out.println("st2.i = "+st2.i);
Incrementable.increment();
System.out.println("After Incrementable.increment called:");
System.out.println("st1.i = "+st1.i);
System.out.println("st2.i = "+st2.i);
}
}
StaticTest.i = 47
st1.i = 47
st2.i = 47
After sf.increment called:
st1.i = 48
st2.i = 48
After Incrementable.increment called:
st1.i = 49
st2.i = 49
练习8:(3)编写一个程序,展示无论你创建了某个特定类的多少个对象,这个类中的某个特定的 static域只有一个实例。
class StaticTest {
static int i = 47;
}
class Incrementable {
static void increment() { StaticTest.i++; }
}
public class OneStaticTest {
public static void main(String[] args) {
System.out.println("StaticTest.i= " + StaticTest.i);
StaticTest st1 = new StaticTest();
StaticTest st2 = new StaticTest();
System.out.println("st1.i= " + st1.i);
System.out.println("st2.i= " + st2.i);
Incrementable.increment();
System.out.println("After Incrementable.increment() called: ");
System.out.println("st1.i = " + st1.i);
System.out.println("st2.i = " + st2.i);
Incrementable.increment();
System.out.println("After Incrementable.increment called: ");
System.out.println("st1.i = " + st1.i);
System.out.println("st2.i = " + st2.i);
st1.i = 3;
System.out.println("After st1.i = 3, ");
System.out.println("st1.i = " + st1.i);
System.out.println("st2.i = " + st2.i);
System.out.println("Create another StaticTest, st3.");
StaticTest st3 = new StaticTest();
System.out.println("st3.i = " + st3.i);
}
}
StaticTest.i= 47
st1.i= 47
st2.i= 47
After Incrementable.increment() called:
st1.i = 48
st2.i = 48
After Incrementable.increment called:
st1.i = 49
st2.i = 49
After st1.i = 3,
st1.i = 3
st2.i = 3
Create another StaticTest, st3.
st3.i = 3
练习9:(2)编写一个程序,展示自动包装功能对所有的基本类型和包装器类型都起作用。
public class AutoboxTest {
public static void main(String[] args) {
boolean b = false;
char c = 'x';
byte t = 8;
short s = 16;
int i = 32;
long l = 64;
float f = 0.32f;
double d = 0.64;
Boolean B = b;
System.out.println("boolean b = " + b);
System.out.println("Boolean B = " + B);
Character C = c;
System.out.println("char c = " + c);
System.out.println("Character C = " + C);
Byte T = t;
System.out.println("byte t = " + t);
System.out.println("Byte T = " + T);
Short S = s;
System.out.println("short s = " + s);
System.out.println("Short S = " + S);
Integer I = i;
System.out.println("int i = " + i);
System.out.println("Integer I = " + I);
Long L = l;
System.out.println("long l = " + l);
System.out.println("Long L = " + L);
Float F = f;
System.out.println("float f = " + f);
System.out.println("Float F = " + F);
Double D = d;
System.out.println("double d = " + d);
System.out.println("Double D = " + D);
}
}
boolean b = false
Boolean B = false
char c = x
Character C = x
byte t = 8
Byte T = 8
short s = 16
Short S = 16
int i = 32
Integer I = 32
long l = 64
Long L = 64
float f = 0.32
Float F = 0.32
double d = 0.64
Double D = 0.64
练习10:(2)编写一个程序,打印出从命令行获得的三个参数。为此,需要确定命令行数组中 String的下标。
public class CommandArgTest {
public static void main(String[] args) {
System.out.println("args[0] = "+args[0]);
System.out.println("args[1] = "+args[1]);
System.out.println("args[2] = "+args[2]);
}
}
练习11:(1)将 AllTheColorsRainbow这个示例改写成一个程序,然后编译、运行。
public class Rainbow {
public static void main(String[] args) {
AllTheColorsOfTheRainbow atc = new AllTheColorsOfTheRainbow();
System.out.println("atc.anIntegerRepresentingColors ="+atc.anIntegerRepresentingColors);
atc.changeColor(7);
atc.changeTheHueOfTheColor(77);
System.out.println("atc.anIntegerRepresentingColors ="+atc.anIntegerRepresentingColors);
System.out.println("atc.hue = " + atc.hue);
}
}
class AllTheColorsOfTheRainbow {
int anIntegerRepresentingColors = 0;
int hue = 0;
void changeTheHueOfTheColor(int newHue){
hue = newHue;
}
int changeColor(int newColor){
return anIntegerRepresentingColors = newColor;
}
}
atc.anIntegerRepresentingColors =0
atc.anIntegerRepresentingColors =7
atc.hue = 77
练习12:(2)找出 Hello. javap的第二版本,也就是那个简单注释文档的示例。对该文件执行 javadoc,然后通过Web浏览器观看运行结果。
import java.util.*;
/**
* @author Tangwenbo
* @version JDK 1.8
* @date 2021/7/11 15:54
*/
public class DocTest {
/** Entry poing 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)
*/
练习13:(1)通过 Javadoc运行 Documentation1 . java, Documentation2.java和 Documentation3 .java,然后通过Web浏览器验证所产生的文档。
/**
* @author Tangwenbo
* @version JDK 1.8
* @date 2021/7/8 23:35
*/
//: object/Documentation1.java
/** A class comment*/
public class Documentation1 {
/** A field comment*/
public int i;
/** A method comment*/
public void f(){};
} ///:~
import java.util.Date;
/**
* @author Tangwenbo
* @version JDK 1.8
* @date 2021/7/11 16:15
*/
// object/Documentation2.java
/**
* <pre>
* Uses
* System.out.println(new Date());
* </pre>
*/
public class Documentation2 {
Date d = new Date();
void showDate() {
System.out.println("Date = " + d);
}
}
import java.util.*;
/**
* @author Tangwenbo
* @version JDK 1.8
* @date 2021/7/11 16:18
*/
// object/Documentation3.java
/**
* You can even insert a list:
* <ol>
* <li> Item one
* <li> Item two
* <li> Item three
* </ol>
*/
public class Documentation3 {
public static void main(String[] args) {
Date d = new Date();
System.out.println("d = " + d);
}
}
练习14:(1)在前一个练习的文档中加入各项的HTML列表。
/**
* @author Tangwenbo
* @version JDK 1.8
* @date 2021/7/11 16:21
*/
import java.util.*;
// object/Documentation4.java
/**
* You can even insert a list:
* <ol>
* <li> Item one
* <li> Item two
* <li> Item three
* </ol>
* Another test list
* <ol>
* <li> One
* <li> Two
* <li> Three
* </ol>
*/
public class Documentation4 {
/** Let's try a public field list
* <ol>
* <li> One
* <li> Two
* <li> Three
* </ol>
*/
public int i = 2;
/**
* A private field list (-private to see)
* <ol>
* <li> One
* <li> Two
* <li> Three
* </ol>
*/
private int j = 3;
/**
* Another list can be inserted here to help explain the
* following method call
* <ol>
* <li> One
* <li> Two
* <li> Three
* </ol><br>
* but may be formatted differently in Method Summary
*/
public static void main(String[] args) {
/**
* Let's try another test list here
* <ol>
* <li> One
* <li> Two
* <li> Three
* </ol>
*/
Date d = new Date();
System.out.println("d = " + d);
}
}
练习15:(1)使用练习2的程序,加入注释文档。用 javadoc提取此注释文档,并产生一个HTML文件,然后通过Web浏览器査看结果。
/**
* Public class contained in file of the same name that includes main()
*/
public class HelloDocTest {
/** main method executed by java
*/
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
练习16:(1)找到第5章中的 Overloading.java示例,并为它加入 javadoc文档。然后用javadoc提取此注释文档,并产生一个HTML文件,最后,通过Web浏览器查看结果。
/** creates type Tree wth two constructors and one info method
*/
class Tree {
int height;
/** no-argument constructor
* assigns height = 0
*/
Tree() {
System.out.println("Planting a seedling");
height = 0;
}
/** constructor taking an int argument,
* assigns height that int argument
*/
Tree(int initialHeight) {
height = initialHeight;
System.out.println("Creating new tree that is " + height + " feet tall");
}
/** method to print height of tree object
*/
void info() {
System.out.println("Tree is " + height + " feet tall");
}
/** overloaded method to print string argument
* and height of a tree object
*/
void info(String s) {
System.out.println(s + ": Tree is " + height + " feet tall");
}
}
/** class to test construction of tree objects
*/
public class Overloading {
public static void main(String[] args) {
for(int i = 0; i < 5; i++) {
Tree t = new Tree(i);
t.info();
t.info("overloading method");
}
// Overloaded constructor:
new Tree();
}
}