《java编程思想》java复习笔记

《java编程思想》java复习笔记

最近在看《java编程思想》,书挺厚的,但是里面确实有很多东西在学的时候没有注意,重新在读的过程中,找到很多之前没有注意到的东西,在此记录。

第四章、控制执行流程

  1. java中能否使用goto语句?
    goto在java中作为保留字,但是在语言中没有用它。但是java中也可以完成一些相应的操作。标签是后面跟有冒号的标识符,例如 ‘lable:’。标签可以和 break、continue两个关键词连用。若这两个关键词和标签连用,会中断循环,跳转到标签所在的语句。再完成相应的特性(break+标签会跳转到标签处,但不会重新进入循环,而continue会重新进入循环——如果可以的话)。通过这一特性可以一次跳出多重循环。

  2. 在switch-case结构中,有这样的栗子

        public class Test{
            public static void main(String[] args){
                int i = 3;
                switch(i){
                    case 1:
                        System.out.println("1");
                    case 2:
                        System.out.println("2");
                    case 3:
                        System.out.println("3");
                    case 4:
                        System.out.println("4");
                    default:
                        System.out.println("default");
                }
            }
        }
output:
3
4
default

之前一直认为,case会按照冒号前的数值进行匹配,只有匹配的才能执行相应的语句,但是结果却说明这句话只适用于第一个匹配的项,之后的项不会进行匹配,会依次执行case后的语句。另外需要记忆的是,switch的选择因子只能是int、char或者enum类型。

第五章、初始化与清理

  1. override 重写(覆写),对父类中的同名方法进行不同方式的实现,但是不允许修改该方法的的方法签名(方法的名称和其每一个形参的顺序、类型和种类)。但是overload 重载则是多个同名函数具有不同的方法签名,为什么返回值不可以作为判断重载的标志之一呢?
void fun(){...}
int fun(){...}

这样两个方法,在被这样调用的时候fun();编译器就无法区别到底调用那个函数了。

5.5清理:终结处理和垃圾回收

java中有垃圾回收器负责回收无用对象占据的内存资源。但是也有特殊情况下的对象无法被回收(没有使用new获得内存空间),而垃圾回收器只能回收通过new分配的内存。

  1. finalize()方法:一旦垃圾回收器准备好释放对象占用的内存,将首先调用finalize()方法,并且在下一次的垃圾回收动作发生时,才会真正回收对象占用的内存。

  2. 然而java中的对象却并不一定总是被垃圾回收器所回收,即

    • 对象可能不被垃圾回收
    • 垃圾回收不等于“析构”
  3. 只要在程序没有濒临存储空间用光的那一刻,对象占用的空间就总也得不到释放,如果程序结束,并且垃圾回收器一直也没有释放你创建的任何对象的存储空间,随着程序的退出,那些资源也全部交还给系统。换句话说,java虚拟机没有面临内存耗尽的状况时,是不会浪费时间去执行垃圾回收以恢复内存的。

    垃圾回收只与内存有关

  4. 那么finalize()方法到底是用于怎样的需求呢?即通过某种创建对象方式以外的方式为对象分配了内存。当使用了JNI(java native interface java本地接口),java代码和c/c++代码进行了相互调用,在c/c++中使用了malloc函数系列来分配内存空间,自然需要用free函数来释放内存,否则将会造成内存泄露。所以需要用finalize()方法来调用它。

  5. 找到一篇关于垃圾回收机制的博客

今天就先写到这里。。。

2015年3月25日09:26:15

5.6初始化
  1. 声明局部变量时,如果没有顺带的初始化变量,会在编译阶段发生错误。

  2. 但是如果是类成员变量,每个基本类型的数据成员都会被保证有一个初始值(0,false,[],0.0),而引用变量的初始值为null,这个叫做自动初始化。

  3. 需要注意的有一点,构造器可以进行类数据成员的初始化,但是无法阻止自动初始化的进行,因为自动初始化是在构造器被调用之前完成的

  4. 在类的内部,变量定义的顺序决定了初始化的顺序,但是无论这些变量是否在方法之前还是之后被声明,仍旧会在任何方法(包括构造器)之前得到初始化。

  5. 如果父类的构造方法中有被子类重写的方法,执行SuperClass super = new SubClass();时,初始化时调用父类的构造函数,是执行父类的原方法,还是执行子类中被重写的方法呢?有例子:
class SuperClass...{
    public SuperClass()...{
        System.out.println("SuperClass of constructor");
        m();
    }
    public void m()...{
        System.out.println("SuperClass.m()");
    }
}
public class SubClassTest extends SuperClass ...{
    private int i = 10;
    public SubClassTest()...{
        System.out.println("SubClass of constructor");
        super.m();
        m();
    }
    public void m()...{
        System.out.println("SubClass.m(): i = " + i);
    }
    public static void main(String[] args)...{
        SuperClass t = new SubClassTest();
    }
}
/*
可能很多人会认为输出为:
SuperClass of constructor
SubClass.m(): i = 10
SubClass of constructor
SuperClass.m()
SubClass.m(): i = 10
其实不然!
正确输出为:
SuperClass of constructor
SubClass.m(): i = 0
SubClass of constructor
SuperClass.m()
SubClass.m(): i = 10*/

这是什么原因呢?

在生成对象时,父类调用的M()方法,不是父类的 M()方法,而时子类中被重写了的M()方法!!并且还出现一个怪异的现象,子类的privte int i 也被父类访问到,这不是和我们说private的成员只能在本类使用的原则相违背了吗?其实我们说的这条原则是编译期间所遵守的,在JAVA程序的编译期间,它只检查语法的合法性,在JAVA的JVM中,即运行期间,不管你声明的什么,对于JVM来说都是透明的,而多态是在运行期间执行的,所以能拿到SubClass的private成员,一点都不奇怪,只是此时还没执行 i = 10,所以在父类的构造方法中调用m()时,系统只能将i赋予系统初值0。

静态数据的初始化
  1. 静态初始化只有在必要的时刻才会进行,只有在第一个类对象被创建或者第一次访问静态数据的时候,它们才会被初始化。

  2. 初始化的顺序是

    静态对象->非静态对象

  3. 静态块(跟在static关键字后的代码块)与其他静态初始化动作一样,在非静态对象前被初始化。

非静态实例初始化

和静态块初始化类似,只不过在代码块(实例初始化子句)前没有static关键字。例如

public class Dog{
    private int age;
    private int sex;
    {
        age = 1;
        sex = 1;
    }
    public Dog(){}
    public Dog(int age){ this.age = age;}
    //...
}

实例初始化子句会在构造函数被调用前完成操作,保证了不论哪个构造器被调用,都能执行统一的操作。

2015年4月4日21:00:39

8多态

8.2.1方法调用的绑定

将方法调用和一个方法主体关联起来叫做绑定
若在程序执行前进行绑定,叫做前期绑定,如果在运行时根据对象类型进行绑定,叫做后期绑定

后期绑定也被称作动态绑定,保证了多态的实现。

8.3.3 构造器内部的多态方法的行为

参看5.6初始化 第五条的示例
用尽可能简单的方法使得对象进入正常状态,如果可以的话,不要调用其他方法(尤其是能被子类重写的方法)。在构造器中唯一能安全调用的是基类中的final方法(也包括private方法,它们自动属于final方法)。这些方法不能被覆盖,因此也就不会出现上面的问题。

8.4协变返回类型

在子类中的被覆盖方法的返回值类型,可以是父类该方法返回值类型的子类。即

class Flower{
    public Flower(){System.out.println("flower");} 
}

class Rose extends Flower{
    public Rose(){System.out.println("rose");}
}

class Factory{
    public Factory(){}
    public Flower getFlower(){return new Flower;}
}

class RoseFactory{
    public RoseFactory(){}
    public Rose getFlower(){return new Rose();}

    public static void main(String[] args){
        Factory f = new Factory();
        RoseFactory rf = new RoseFactory();
        f.getFlower();
        rf.getFlower();
    }
    /*输出:
    flower
    rose

    */
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
期末考试题型: 一、 填空题(本题共15空 ,每空1分,共15分。) 二、 单项选择题(本题共20小题,每题1分,共20分。) 三、 是非题(对划“√”,错划“×”,本题共10小题,每题1分,共10分。) 四、 简答题(本题共5小题,每小题5分,共25分。) 五、 程序填空题(本题共5空 ,每空2分,共10分。) 六、 编程题(本题共2小题,每小题10分,共20分。) 二、填空题 1、Java语言是一种完全的_面相对象___程序设计语言。 2、布尔型常量有两个值,它们分别是_true__、_false___。 3、在定义一个方法时,一般都要指明该方法的返回值类型,如果它不返回任何值,则必须将其声明成 void 。 4、在Java的语言环境中已经包含了一组相关的核心类库,它们属于Java.lang包。 5、写出完整的main方法的声明 public static void main(String args[]) 。 6、要设计一个Applet小程序,必须先引入包 java.applet 。 7、设x=2.5,a=7,y=4.7,算术表达式x+a%3*(int)(x+y)%2/4的值为:2.75___ 8、被关键字_final___修饰的方法是不能被当前类的子类重新定义的方法。 9、Java中类成员的限定词有以下几种:private, _protected__, public__, 默认友好。 10、基类的公有成员在派生类中的访问权限由_基类___决定。 11、用static修饰的方法,称为静态方法。它们不是对象的方法,而是整个类的方法。静态方法只能处理用关键字_static___修饰的数据。 12、在Java中有一种叫作__构造方法__的特殊方法,我们在程序中用它来对类的对象成员进行初始化。 13、面向对象技术具有_封装性___、_继承性___、_抽象性___、多态性等特性。 14、Java中所有类都是类 _Object___的子类。 15、顺序执行以下两个语句的输出结果是: 10 。 String s = “我喜欢学习Java!”; System.out.println(s.length( )); 16、据程序的构成和运行环境的不同,Java源程序分为两大类: Application 程序和 Applet 程序。 17、如果一个Java源程序文件中定义有4个类,则使用Sun公司的JDK编译器javac编译该源程序文件将产生 4 个文件名与类名相同而扩展名为 class 的字节码文件。 18、开发与运行Java程序需要经过的三个主要步骤为 编辑源文件 、 编译器编译生成字节码文件 和 解释器执行 。 19、如果一个Java Applet源程序文件只定义有一个类,该类的类名为MyApplet,则类MyApplet必须是 Applet 类的子类并且存储该源程序文件的文件名必须为 MyApplet.java 。 20、 一个Java Application源程序文件名为MyJavaApplication.java,如果使用Sun公司的Java开发工具JDK编译该源程序文件并使用其虚拟机运算这个程序的字节码文件,应该顺序执行如下两个命令: javac MyJavaApplication.javajava MyJavaApplication 。 21、在Java的基本数据类型中,char型采用Unicode编码方案,每个Unicode码字符占用 2 字节内存空间,这样,无论是中文字符还是英文字符,每个都是占用2 字节内存空间。 22、在Java程序中定义的类有两种成员: 静态成员 、 实例成员 。 23、Java源程序是由类定义组成的,每个程序中可以定义若干个类,但是只有一个类是主类。在Java Application中,这个主类是指包含 main 方法的类;在Java Applet里,这个主类是一个系统类 Applet 的子类。 24、创建一个名为 MyPackage 的包的语句是 package MyPackage ; , 该语句应该放在程序的位置为: 程序中非注释行的第一行 。 25、 抽象或abstract 方法是一种仅有方法头,没有具体方法体和操作实现的方法,该方法必须在抽象类之中定义。 最终后final 方法是不能被当前类的子类重新定义的方法。 26、多态是指 一种定义,多种实现 ,在Java中有两种多态,一种是使用方法的 重载 实现多态,另一种是使用方法的 覆盖 实现多态。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值