知识点:
finally 块前面必须有 try 块,不要把 finally 块单独拉出来使用。编译器也不允许这样做。
finally 块不是必选项,有try 块的时候不一定要有 finally 块。
如果 finally 块中的代码可能会发生异常,也应该使用 try-catch 进行包裹。
即便是 try 块中执行了 return、break、continue 这些跳转语句,finally 块也会被执行。
需要知道一点,就是当try中发生了异常并且被catch处理了,并且try和catch里都没有return语句那程序会继续执行,直到方法结束。
所以上面这个题换一下,变成,catch里面没有return语句,那他的输出结果就应该是12012.
上面的结果是1201.
这道题错了简直就是,“惯性思维了”。
不可以像调用普通函数一样调用构造函数。
构造器
子类构造方法默认调用父类的无参构造方法,如果父类没有无参构造,那么子类会报错。这是因为每一个子类构造都会默认有一行super()
当父类没写无参构造那你子类也不用写构造函数,因为你写了也报错。
当父类无无参函数,但是有子类构造函数,你子类的每一个构造函数需要使用super()
调用的父类的构造函数(任意那个父类构造都可以)
像这样:
想要不报错:
两种super都可以。
所以平时为了方便不写那么多的super,所以乖乖的在父类写上无参构造。可以避免很多不必要的麻烦。
那我们说一个抽象类继承:我们都知道抽象类是不可以实例化的,那为什么还需要给他写无参构造呢,
答案:是为了限制子类的构造行为。
java初始化顺序
new sub()会去调用子类的构造函数,但是sub继承自base,所以执行子类构造方法时回去先调用父类的无参构造,
而父类的无参构造又调用了callName()这个方法,是子类重写的,本着编译看左边,运行看右边的原则,他回去找子类重写的callName()方法,但是子类此时的构造方法还没有完成呢,所以子类的baseName="sub"还没有初始化呢,所以baseName为null
基本数据类型 | 取值范围 | 字节 |
---|---|---|
byte | [-128~127] | 1 |
short | [ -32768~32767] | 2 |
int | [-2147483648~2147483647] | 4 |
long | [-9223372036854774808~9223372036854774807] | 8 |
还有所有的数据是一个环,正数到了最大,就继续从负数最小的内个开始循环。
就好像无穷的尽头是0,0的尽头是无穷。
所以当出现byte a = (byte)129的时候他打印出来是-127
hashcode和equals
每个对象都会有自己的hashcode。equals和hashcode都是用来比较两个对象是否一致的。hashcode是将对象的地址值映射为Integer类型的哈希值,不同的对象可能经过相同的hash算法产生相同的code值,所以说hashcode并不可靠。
当比较了hashcode之后再去比较equeals,两者不同才会判定为不同,两者hashcode相同但equals不同,这两个对象也是不一样的。
所以equals是用来保证可靠的。
我觉得equals是比hashcode更严格的筛选,所以他可能就比hashcode更“重”。
一句话:hashcode相同的对象,equals不一定相同,但equals相同的,hashcode一定相同。hashcode保证效率,equals保证可靠。