温故而知新Java基础--用浅显易懂的文字持续更新

221 阅读5分钟

1. 一句话说明this

  • this就是所在函数所属对象的引用。

    简单说:哪个对象调用了this所在的函数,this就代表哪个对象

      下图中的this代表啥呢?
      图片左边中的第9行代码,person1调用了this的equals(Object obj)方法,
      那这个this指的就是person1。
    

  • this也可以用于在构造函数中调用其他构造函数。比如在带两个参数的构造函数中调用带一个参数的构造函数。
  • 注意:只能定义在构造函数的第一行。因为初始化动作要先执行。
Person(String name)
{
    this.name = name;
}
Person(String name, int age)
{
    this(name); //在构造函数中调用其他构造函数
    this.age = age;
}

2. 匿名内部类

匿名内部类,就是内部类的简写格式。

必须有前提: 匿名内部类必须继承或者实现一个外部类或者接口

匿名内部类:其实就是一个匿名子类对象。

格式:new 父类or接口(){子类内容}

怎么理解(记忆)呢?

匿名内部类,你没有名字,那在new对象的时候new后面写啥名呢,没法写啊,
因为匿名内部类是没有名的啊,
所以,new关键字后面得写父类或接口的名字,
所以,匿名内部类必须继承或者实现一个外部类或者接口。

3. static静态变量/static静态方法为什么可以直接使用类名.调用?

静态变量随着类的加载而加载的,在静态区中存着(不在堆中,不在栈中),所以不用先new对象,然后再用对象.来调用。

4. 多态时,成员的特点

  1. 成员变量
简单说:编译和运行都参考等号的左边。
  1. 成员函数(非静态)
简单说:编译看左边,运行看右边。因为成员函数存在覆盖特性。
* 向上转型会隐藏子类特有的变量和方法(猫一旦变成动物,你想调用它的抓老鼠方法就不行了)
* 扩展的时候向上转型
    Animal ani = new Cat();
* 使用特有功能的时候向下转型 
    ani = (Cat)ani;
    ani.catchMouse();
* 所以父类引用.被子类覆盖的方法()执行的是子类的具体实现方式
* 所以父类引用.子类特有的方法/变量会报错
编译时:参考引用型变量所属的类中的是否有调用的函数。
有,编译通过,没有,编译失败。
运行时:参考的是对象所属的类中是否有调用的函数。
package javapractise;
public class DuoTai {
	public static void main(String[] args) {
	    Fu fu = new Zi();
	    Zi zi = new Zi();
	    System.out.println(fu.num);  // 运行结果:10
	    System.out.println(zi.num);  // 运行结果:1000
	    fu.show(); // 运行结果:Zi show
	    zi.show(); // 运行结果:Zi show	
	}
}
class Fu {
	int num = 10;

	void show() {
	    System.out.println("Fu show");
	}
}
class Zi extends Fu{
	int num = 1000;

	void show() {
	    System.out.println("Zi show");
	}
}
  1. 静态函数
简单说,编译和运行都看左边。
其实对于静态方法,是不需要对象的。直接用类名调用即可。

5. 子类父类异常的注意事项

  1. 子类在覆盖父类方法时,父类的方法如果抛出了异常,那么子类的方法只能抛出父类的异常或者该异常的子类

  2. 如果父类抛出多个异常,那么子类只能抛出父类异常的子集。

    简单说:子类覆盖父类只能抛出父类的异常或者子类或者子集

  3. 如果父类的方法没有抛出异常,那么子类覆盖时绝对不能抛,就只能try。

怎么理解(记忆)呢?

有一个父类,这个父类只抛出类型转换异常,
程序员A在一月份写了一堆使用到这个父类的主程序代码,
他知道这个父类只抛出类型转换异常,
程序员A在主程序中就只涉及处理这一个异常。

二月份,程序员B写了一个子类,继承上面的父类,
抛出了另外一个异常(假如这种情况允许的话),
那主程序再运行的时候是不是就挂了啊,
因为主程序不会处理这个新异常啊。
Java肯定不允许这样的事情发生啊。

6. import导包真正导入的是什么?

import导包其实不是导包,是导入包中的类。或者说import导入的是包中的类,它不导入包中的包。

在学习初期你是不是也有过如下疑问: 上面那一条导入语句com.abc文件夹下的所有文件都导入了,这里为什么还必须要在导入一次com.abc下的www文件夹下的类呢?

其实是因为, import导入的是包中的类,它不导入包中的包。

package com.xxx.yyy

import com.abc.*;
// 上面那一条导入语句com.abc文件夹下的所有文件都导入了,
// 这里为什么还必须要在导入一次com.abc下的www文件夹下的类呢?
import com.abc.www.*;
class Demo{
    // 代码
}

7. System.gc()运行垃圾回收器,为什么不立即将垃圾回收呢?

可能你以前听说过的解释是这样的:垃圾回收器什么时候回收垃圾是由JVM(Java虚拟机)决定的。

这里换个角度解释一下: 执行main函数的是一个线程,负责垃圾回收的是另一个线程。因为具体什么运行垃圾回收线程不是我们调用就能决定的,得看CPU何时给垃圾回收线程分配时间。在主函数中显示调用System.gc()没用。

8. String类的trim()方法到底能截掉什么?

截掉了字符串两端的ASCII码表中小于32的字符。或者说是将字符串两端的ASCII码表中空格之前的字符都截掉了。

注意这里的空格指的是半角输入法输入的标准空格。是ASCII码为32的空格,不是160的那个空格。

9. 自动装箱,如果装箱的是一个字节(小于等于127),那么该数据就会被共享,不会重新开辟空间。