JavaSE基础常见的问题
1、抽象类和接口的区别
(参考文章:https://www.cnblogs.com/songhuiqiang/p/10647835.html)
~抽象类:抽象类是用来捕捉子类的通用特性的 。它不能被实例化,只能被用作子类的超类。抽象类是被用来创建继承层级里子类的模板,抽象类可以不定义抽象方法,如果定义抽象方法,子类一定要去实现抽象方法。
~接口:接口是抽象方法的集合。如果一个类实现了某个接口,那么它就继承了这个接口的抽象方法。这就像契约模式,如果实现了这个接口,那么就必须确保使用这些方法。接口只是一种形式,接口自身不能做任何事情。

2、this关键字
this.属性名称 : 指的是访问类中的成员变量,用来区分成员变量和局部变量(重名问题)
this.方法名称 :用来访问本类的成员方法
this(): 访问本类的构造方法()中可以有参数的 如果有参数 就是调用指定的有参构造(PS:只能写在构造方法里,并且是第一条语句)
3、static关键字
(参考文章:https://www.cnblogs.com/dolphin0520/p/3799052.html)
static的作用就是方便在没有创建对象的情况下来进行调用(方法/变量)。
很显然,被static关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就可以通过类名去进行访问。
static可以用来修饰类的成员方法、类的成员变量,另外可以编写static代码块来优化程序性能。
1) static方法
static方法一般称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。
但是要注意的是,虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法/变量的。因此,如果说想在不创建对象的情况下调用某个方法,就可以将这个方法设置为static。我们最常见的static方法就是main方法,至于为什么main方法必须是static的,现在就很清楚了。因为程序在执行main方法的时候没有创建任何对象,因此只有通过类名来访问。
2)static变量
static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。
3)static代码块
static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
Question:
1、static关键字会改变类中成员的访问权限吗?
static关键字不会影响到变量或者方法的作用域
2、能通过this访问静态成员变量吗?
可以访问本对象中的静态成员变量
4、双亲委派机制
(参考文章:https://www.jianshu.com/p/1e4011617650)
1)什么是双亲委派机制
当某个类加载器需要加载某个.class文件时,它首先把这个任务委托给他的上级类加载器,递归这个操作,如果上级的类加载器没有加载,自己才会去加载这个类。
2)类加载器的类别
BootstrapClassLoader(启动类加载器)
c++编写,加载java核心库 java.*,构造ExtClassLoader和AppClassLoader。由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作
ExtClassLoader (标准扩展类加载器)
java编写,加载扩展库,如classpath中的jre ,javax.*或者java.ext.dir 指定位置中的类,开发者可以直接使用标准扩展类加载器。
AppClassLoader(系统类加载器)
java编写,加载程序所在的目录,如user.dir所在的位置的class
CustomClassLoader(用户自定义类加载器)
java编写,用户自定义的类加载器,可加载指定路径的class文件
3)双亲委派机制的作用
(1)防止重复加载同一个.class。通过委托去向上面问一问,加载过了,就不用再加载一遍。保证数据安全。
(2)保证核心.class不能被篡改。通过委托方式,不会去篡改核心.clas,即使篡改也不会去加载,即使加载也不会是同一个.class对象了。不同的加载器加载同一个.class也不是同一个Class对象。这样保证了Class执行安全。
5、Java语法糖
(具体文章参考:https://www.cnblogs.com/54chensongxia/p/11665843.html)
1)语法糖(Syntactic Sugar),也称糖衣语法,指在计算机语言中添加的某种语法,这种语法对语言本身的功能来说没有什么影响,只是为了方便程序员进行开发,提高开发效率,使用这种语法写出来的程序可读性也更高。说白了,语法糖就是对现有语法的一个封装。但其实,Java虚拟机是并不支持语法糖的,语法糖在程序编译阶段就会被还原成简单的基础语法结构,这个过程就是解语法糖。所以在Java中真正支持语法糖的是Java编译器。
2)常见的语法糖:
- switch-case对String和枚举类的支持
- 泛型
- 包装类自动装箱与拆箱
- 方法变长参数
- 枚举
- 内部类
- 条件编译
- 断言
- 数值字面量
- 增强for循环
- try-with-resource语法
- Lambda表达式
- 字符串+号语法
6、注解
(参考文章:菜鸟教程注解详解)
Java 语言中的类、方法、变量、参数和包等都可以被标注。主要作用可以通过反射获取注解中的内容,在编译器生成类文件时,标注可以被嵌入到字节码中。Java 虚拟机可以保留标注内容,在运行时可以获取到标注内容 。
内置的注解
一共有七个,3个在lang包下,4个在lang.anotation中
- @Override - 检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。
- @Deprecated - 标记过时方法。如果使用该方法,会报编译警告。
- @SuppressWarnings - 指示编译器去忽略注解中声明的警告。
作用在其他注解的注解(元注解):
- @Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。
- @Documented - 标记这些注解是否包含在用户文档中。
- @Target - 标记这个注解应该是哪种 Java 成员。
- @Inherited - 标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)
从 Java 7 开始,额外添加了 3 个注解:
- @SafeVarargs - Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。
- @FunctionalInterface - Java 8 开始支持,标识一个匿名函数或函数式接口。
- @Repeatable - Java 8 开始支持,标识某注解可以在同一个声明上使用多次。
1)架构

ElementType注解:包含了定义在某处的声明如TYPE(接口、类、枚举)、FIELD(字段)、METHOD(方法)、PARAMETED(参数)、CONSTRUCTOR(构造方法)等
RetentionPolicy注解:包含了编译器在何时处理Annotation信息,一般情况下都使用RUNTIME
每 1 个 Annotation" 都与 "1 个 RetentionPolicy" 关联,并且与 "1~n 个 ElementType" 关联
举例:
@Documented @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation1 { String value() default "";//这不是方法而是参数类型,需要在使用该注解的时候赋值。 }
其他的注解:
@Deprecated -- @Deprecated 所标注内容,不再被建议使用。 @Override -- @Override 只能标注方法,表示该方法覆盖父类中的方法。 @Documented -- @Documented 所标注内容,可以出现在javadoc中。 @Inherited -- @Inherited只能被用来标注“Annotation类型”,它所标注的Annotation具有继承性。 @Retention -- @Retention只能被用来标注“Annotation类型”,而且它被用来指定Annotation的RetentionPolicy属性。 @Target -- @Target只能被用来标注“Annotation类型”,而且它被用来指定Annotation的ElementType属性。 @SuppressWarnings -- @SuppressWarnings 所标注内容产生的警告,编译器会对这些警告保持静默。
注解还具有具有"让编译器进行编译检查的作用"。
2)注解经常和反射一起联合使用,框架的底层实现原理基本都用到了注解和反射,由此可见注解和反射的重要性
7、反射
反射就是把Java类中的各个成分映射成一个个的Java对象。即在运行状态中,对于任意一个类,都能够知道这个类的所以属性和方法;对于任意一个对象,都能调用它的任意一个方法和属性。这种动态获取信息及动态调用对象方法的功能叫Java的反射机制。
1)Class类中常用的方法:
-
getName():获得类的完整名字。 getFields():获得类的public类型的属性。
-
getDeclaredFields():获得类的所有属性。
-
getMethods():获得类的public类型的方法。
-
getDeclaredMethods():获得类的所有方法。
-
getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes参数指定方法的参数类型。
-
getConstrutors():获得类的public类型的构造方法。
-
getConstrutor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes参数指定构造方法的参数类型。
-
newInstance():通过类的不带参数的构造方法创建这个类的一个对象。
8、Iterator迭代器
Iterator不是一个集合,它是一种用于访问集合的方法,可用于迭代 ArrayList 和 HashSet 等集合。
迭代器 it 的两个基本操作是 next 、hasNext 和 remove。
调用 it.next() 会返回迭代器的下一个元素,并且更新迭代器的状态。
调用 it.hasNext() 用于检测集合中是否还有元素,常与while循环使用,判断集合的下一个是否有值。
调用 it.remove() 将迭代器返回的元素删除。

浙公网安备 33010602011771号