练习1:创建一个类,它包含一个未初始化的String引用。验证该引用被Java初始化成了null。
class Test{
String s;
}
public class Initialization {
public static void main(String[] args) {
Test t=new Test();
System.out.println("s=: "+t.s);
}
}
s=: null
练习2:创建一个类,它包含一个在定义时就被初始化了的String域,以及另一个通过构造器初始化的String域。这两种方式有何差异?
public class Test5_1_2 {
public static void main(String[] args) {
Test1 t = new Test1();
System.out.println(t.s1+" "+t.s2);
t.s2 = "cba";
System.out.println(t.s1+" "+t.s2);
}
}
class Test1{
String s1 = "abc";
String s2;
}
abc null
abc cba
差别在于:
s1初始化了一次,而s2初始化了两次
s1一开始被初始化为”abc”,而s2先被初始化为null,然后再被初始化为”cba”
练习3:创建一个带默认构造器(即无参构造器)的类,在构造器中打印一条消息。为这个类创建一个对象。
class Test{
Test(){
System.out.println("this is a Test");
}
}
public class Initialization {
public static void main(String[] args) {
Test t=new Test();
}
}
练习4:为前一个练习中的类添加一个重载构造器,令其接受一个字符串参数,并在构造器中把你自己的信息和接受的参数一起打印出来。
class Test{
Test(){
System.out.println("this is a Test");
}
Test(String s){
System.out.println("Test: "+s);
}
}
public class Initialization {
public static void main(String[] args) {
Test t=new Test("hello");
}
}
Test: hello
练习5:创建一个名为Dog的类,它具有重载的bark()方法。此方法应根据不同的基本数据类型进行重载,并根据被调用的版本,打印出不同类型的狗吠(barking)、咆哮(howling)等信息。编写main()来调用所有不同版本的方法。
class Dog{
Dog(){
System.out.println("wang wang wang");
}
Dog(String s){
System.out.println(s);
}
Dog(int i){
System.out.println("howling"+i);
}
}
/**
* Initialization
*/
public class Initialization {
public static void main(String[] args) {
Dog d=new Dog();
Dog d2=new Dog("hello");
Dog d3=new Dog(5);
}
}
练习6:修改前一个练习的程序,让两个重载方法各自接受两个类型的不同的参数,但二者顺序相反。验证其是否工作。
class Dog{
Dog(){
System.out.println("wang wang wang");
}
Dog(int i,String s){
System.out.println(s+" "+i);
}
}
/**
* Initialization
*/
public class Initialization {
public static void main(String[] args) {
Dog d2=new Dog("hello",5);
}
}
结果:String不能转成int,int不能转成String
练习7:创建一个没有构造器的类,并在main()中创建其对象,用以验证编译器是否真的自动加入了默认构造器。
//: Main.java
/**
* 默认构造器
*/
class Test {
String s = "Hello World";
}
class Main {
public static void main(String[] args) {
Test t = new Test();
System.out.println(t.s);
}
}
/**
* Output:
Hello World
*///:~
练习8:编写具有两个方法的类,在第一个方法内调用第二个方法两次:第一次调用时不使用this关键字,第二次调用时使用this关键字——这里只是为了验证它是起作用的,你不应该在实践中使用这种方法。
//: Main.java
/**
* 默认构造器
*/
class Test {
private void method1() {
System.out.println("This is method 1.");
}
public void method2() {
method1();
this.method1();
}
}
class Main {
public static void main(String[] args) {
Test t = new Test();
t.method2();
}
}
/**
* Output:
This is method 1.
This is method 1.
*///:~
练习9:编写机油两个(重载)构造器的类,并在第一个构造器中通过this调用第二个构造器。
//: Main.java
/**
* 默认构造器
*/
class Test {
Test (int t) {
System.out.println("This is " + t);
}
Test (String s, int t) {
this(t);
System.out.println("This is " + s);
}
}
class Main {
public static void main(String[] args) {
Test t = new Test("Hello", 42);
}
}
/**
* Output:
This is 42
This is Hello
*///:~
练习10:编写具有finalize()方法的类,并在方法中打印消息。在main()中为该类创建一个对象。试解释这个程序的行为
public class Exercise510 {
@Override
protected void finalize() throws Throwable {
System.out.println("finalize() called");
}
public static void main(String[] args) {
new Exercise510(); // 可能不会看到被调用的终结器,因为程序通常不会为收集器生成足够的垃圾来运行
}
}
练习11:修改前一个练习的程序,让你的finalize()总会被调用。
public class Exercise511 {
@Override
protected void finalize() {
System.out.println("finalize() called");
}
public static void main(String[] args) {
new Exercise511();
System.gc();
System.runFinalization();
}
}

练习12:编写名为Tank的类,此类的状态可以是“满的”或“空的”。
其终结条件是:对象被清理时必须处于空状态。请编写finalize()
以检验终结条件是否成立。在main()中测试Tank可能发生的几种使用方式。
class Tank {
static int counter;
int id = counter++;
boolean full;
public Tank() {
System.out.println("Tank " + id + " created");
full = true;
}
public void empty() {
full = false;
}
@Override
protected void finalize() {
if(full) {
System.out.println("Error: tank " + id + " must be empty at cleanup");
} else {
System.out.println("Tank " + id + " cleaned up OK");
}
}
@Override
public String toString() {
return "Tank " + id;
}
}
public class Exercise512 {
public static void main(String[] args) {
new Tank().empty();
new Tank();
System.gc();
System.runFinalization();
}
}

练习14:编写一个类,拥有两个静态字符串域,其中一个在定义处初始化,
另一个在静态块中初始化。现在,加入一个静态方法用以打印出两个字段值。
请证明它们都会在被使用之前完成初始化动作。
public class Exercise514 {
static String s1 = "Initialized at definition";
static String s2;
static {
s2 = "Initialized in satic block";
}
public static void main(String[] args) {
System.out.println("s1 = " + s1);
System.out.println("s2 = " + s2);
}
}

练习15:编写一个含有字符串域的类,并采用实例初始化方式进行初始化。
public class Exercise515 {
String str;
{
str = " instance initialization";
}
public Exercise515() {
System.out.println("Default constructor: " + str);
}
public Exercise515(String str) {
this.str = str;
System.out.println("constructor: " + str);
}
public static void main(String[] args) {
new Exercise515();
new Exercise515("exercise");
}
}

练习16:创建一个String对象数组,并为每一个元素都赋值一个String。用for循环来打印该数组。
//: StringArray.java
import java.util.Arrays;
public class StringArray {
public static void main(String[] args) {
int num = 5;
String[] sa = new String[num];
for (int i=0; i<num; ++i) {
sa[i] = "Girl[" + i + "]";
}
System.out.println(Arrays.toString(sa));
}
}
/**
* Output:
[Girl[0], Girl[1], Girl[2], Girl[3], Girl[4]]
*/
练习17:创建一个类,它有一个接受一个String参数的构造器。在构造阶段,打印该参数。创建一个该类的对象引用数组,但是不实际去创建对象赋值给该数组。当运行程序时,请注意来自对该构造器的调用中的初始化消息是否打印了出来。
练习18:通过创建对象赋值给引用数组,从而完成前一个练习。
//: StringArray.java
import java.util.Arrays;
class StringExample {
String str;
StringExample(String str) {
this.str = str;
System.out.println("para = " + str);
}
@Override
public String toString() {
return str;
}
}
public class StringArray {
public static void main(String[] args) {
int num = 5;
StringExample[] sea = new StringExample[5];
System.out.println(Arrays.toString(sea));
for (int i=0; i<num; ++i) {
sea[i] = new StringExample("Girl[" + i + "]");
}
System.out.println(Arrays.toString(sea));
}
}
/**
* Output:
[null, null, null, null, null]
para = Girl[0]
para = Girl[1]
para = Girl[2]
para = Girl[3]
para = Girl[4]
[Girl[0], Girl[1], Girl[2], Girl[3], Girl[4]]
*/
练习19:写一个类,它接收一个可变参数的String数组。
验证你可以向该方法传递一个用逗号分隔的String列表,或是一个String[]。
public class Variable {
Variable(String... strs){
for(String s:strs){
System.out.print(s+" ");
}
}
public static void main(String[] args) {
new Variable("hello","world");
System.out.println();
new Variable(new String[]{"haha","hehe","heihei"});
}
}
hello world
haha hehe heihei
练习20:创建一个使用可变参数列表而不是普通的main()语法的main()。
打印所产生的args数组的所有元素,并用各种不同数量的命令行参数来测试它。
public class OtherMain {
public static void main(String... args) {
for (String s : args) {
System.out.print(s + " ");
}
System.out.println();
}
}
/**
* Output:
* haha ahah haah ahha
*///:~
练习21:创建一个enum,它包含纸币中最小面值的6种类型。通过values()循环并打印每一个值及其ordinal()。
/**
* TestEnum
*/
public class TestEnum {
private enum Money{
HUNDRED,
FIFTY,
TEN
}
public static void main(String[] args) {
for(Money m:Money.values()){
System.out.print(m+":"+m.ordinal()+" ");
switch(m){
case HUNDRED:
System.out.println(100);
break;
case FIFTY:
System.out.println(50);
break;
case TEN:
System.out.println(10);
break;
default:
break;
}
}
}
}
练习22:在前面的例子中,为enum写一个switch语句,
对于每一个case,输出该特定货币的描述。
//: TestEnum.java
/**
* 练习使用Enum, values(), ordinal(), switch
* Created by wang on 15/7/30.
*/
public class TestEnum {
private enum Money {
HUNDRED, FIFTY, TWENTY, TEN, FIVE, TWO, ONE
}
public static void main(String[] args) {
for (Money m : Money.values()) {
System.out.print(m + ":" + m.ordinal() + " ");
switch (m) {
case HUNDRED:
System.out.println("$" + 100);
break;
case FIFTY:
System.out.println("$" + 50);
break;
case TWENTY:
System.out.println("$" + 20);
break;
case TEN:
System.out.println("$" + 10);
break;
case FIVE:
System.out.println("$" + 5);
break;
case TWO:
System.out.println("$" + 2);
break;
case ONE:
System.out.println("$" + 1);
break;
default:
break;
}
}
System.out.println();
}
}
/**
* Output:
HUNDRED:0 $100
FIFTY:1 $50
TWENTY:2 $20
TEN:3 $10
FIVE:4 $5
TWO:5 $2
ONE:6 $1
*///:~
&spm=1001.2101.3001.5002&articleId=108736730&d=1&t=3&u=c80975f8e3154c68827ef054b97d9177)
6256

被折叠的 条评论
为什么被折叠?



