摘要:Java知识点精选之类、接口、枚举30问,算是比较基础的,希望大家一起学习进步。

整理了一些JAVA语言的在类、接口、枚举等方面的知识点以及大家常遇到的问题。希望能帮助到大家。

Q: 各修饰符所代表的可见性?
public: 可被所有使用
protect: 只能被自己和子类使用,或者同一个包路径
private: 只能自己使用,儿子都不行
不加修饰符即default权限: 包访问权限,和他在同一包内的类都可以访问他,包外的则都不能访问

Q: 外部类可以用private或者protect修饰吗?
A: 不能,只能用public或者包访问权限。 内部类可以。

解释以下final的作用
Q: final 成员?
A: 如果是基本类型,则指值不能被改变。 如果是对象,指对象的引用不可改变,但是引用处的内容可改变。

Q: final 参数?
A: 参数不可变,只能读不能修改,同上

Q: final方法
A: 方法不能被子类重写。

Q: final类
A: 该类不能被继承。

Q:final局部变量可以作为非final的参数传入吗?会编译报错吗?

public static void main(String[] args){
final A a = new A();
changeA(a);
}
public void changeA(A a) {
// change A...
}

A:可以作为非final的参数传入,不会编译报错。

Q: 重载和重写的区别?
A:重载是方法名相同,参数不同。
重写是方法参数等都一致的情况下重写父类的方法。

Q: 如果子类重载了父类中的方法, 那么子类中还能调用父类中的同名方法吗?
A: 可以(C++中不可以调用父类中的同名重载方法)。

Q: 怎样能避免子类在重写父类的方法,不小心弄成了重载?
(即你想重写父类的f(int), 却不小心写成了f(int,int),导致调用f(int)时还是调用了父类的f ,怎么能避免这种失误?)
A: 加个@Override关键字即可,原文解释:

Q:父类的成员变量能被重写/覆盖嘛?

class A{
public String name = "A";
}
class B extends A{
public String name = "B";
}
public static void main{
A a = new B();
System.out.println(a.name);
}

A:输出A。
注意成员变量不具有多态性,因此你定义的是A,赋值的是B, 那么输出的依旧是A里的成员。
如果是被重写的方法的话,那会用B里的方法。

Q:内部类是啥,内部类能访问外部类的成员吗?
A:
内部类概念:

class A {
class B{
...
}
}

B就是A的内部类,B能访问A的所有成员

Q: A中有1个内部类C, A的子类B中也有1个内部类C, B中的C会覆盖A中的C吗?
A: 不会, 因为使用时是通过B.C或者A.C去调用的,存在命名空间的关系。

Q:可以在内部类中定义静态成员吗?

class A {
class B{
static int b;
...
}
}

A:不可以。 除非在class B前面加static变为静态类

Q: 匿名类是啥, 匿名类能访问外面的变量或者对象吗?
A: 匿名类概念:

return new A(构造参数){
{构造器内容}
类定义
}

匿名类如果要用外面的对象, 外面的对象必须要定义为final。

Q: 嵌套类是啥,能访问外部类的成员吗?
A:

class A {
static int sa;
int a;
static class B{}
}

B只能访问A中的静态成员sa, 而不能访问a。

§ 接口

类是单继承,接口可以多继承

Q: 接口中如果要定义成员变量,那成员的默认修饰符是什么?
A: public static final

Q: 接口中各方法的默认修饰符是什么?
A: public abstract

Q: 接口中可以定义实现具体方法嘛?
A:java8以上版本可以。
引入了default关键字,在接口中用default关键字修饰接口,就可以在接口中去实现这个接口了。

§ 枚举

Q: enum可以被继承吗?
像下面这样:

enum A extend B{
...
}

A: 不可以。enum标识符本身被编译器处理过,自身就继承自Enum类,而java不支持多重继承。但支持实现接口

Q: switch(enum)时需要加default吗?
A: 可以不需要。

Q: Enum基类里实现了values()方法吗?
A: 没有实现, values方法是编译器加的。因此从List<Enum>里取出的对象,是不能调用values()的。

Q:enum里的枚举的默认修饰符默认是?
A:static final

§ 静态分派和动态分派

Q: 下面输出什么,属于什么分派?

 void test() {
Father father = new Son(); //静态分派
print(father);
} void print(Father father) {
System.out.println("this is father");
} void print(Son son) {
System.out.println("this is son");
}

A:输出this is father。 属于静态分派。
静态分派概念: 编译器就能确定调用哪个方法。
这里2个print属于重载方法,通过输入参数的定义类型即立刻确定调用哪个
静态分派取决于静态类型

静态类型概念: 编译期写在java文件里能马上看到的类型
例如 A a = Factory.create(args);
那么左边的A就是静态类型, 而右边的类型取决于运行期,是不确定的。

Q: 上一题的进阶:

public class Overload {
private static void sayHello(char arg){
System.out.println("hello char");
}
private static void sayHello(Object arg){
System.out.println("hello Object");
}
private static void sayHello(int arg){
System.out.println("hello int");
}
private static void sayHello(long arg){
System.out.println("hello long");
}
// 测试代码
public static void main(String[] args) {
sayHello('a');
}
}

输出什么?
A:输出 hello char

因为‘a’是一个char类型数据(即静态类型是char),所以会选择参数类型为char的重载方法。
若注释掉sayHello(char arg)方法,那么会输出 hello int
因为‘a’除了可代表字符串,还可代表数字97。因此当没有最合适的sayHello(char arg)方式进行重载时,会选择第二合适(第二优先级)的方法重载,即sayHello(int arg)

总结:当没有最合适的方法进行重载时,会选优先级第二高的的方法进行重载,如此类推。

优先级顺序为:char>int>long>float>double>Character>Serializable>Object>…
其中…为变长参数,将其视为一个数组元素。变长参数的重载优先级最低。
因为 char 转型到 byte 或 short 的过程是不安全的,所以不会选择参数类型为byte 或 short的方法进行重载,故优先级列表里也没有。

Q: 下面输出什么,属于什么分派:

void test() {
Father father = new Son();
father.name();
} class Son extends Father {
void name(){
System.out.println("son");
}
} class Father {
void name(){
System.out.println("father");
}
}

A:输出son,属于动态分派。运行的时候根据所指向的具体对象才确定调用哪个方法

Q:静态分派属于单分派还是多分派?动态分派属于单分派还是多分派?
A:静态分派是多分派。动态分派是单分派。

多分派概念: 分派时即要考虑调用者的类型,也要考虑参数类型。
而单分派只考虑调用者的类型。

动态分派原理:

Q:类方法在class文件中是什么样的? 是符号引用还是直接引用?

A:class文件中, 所定义的方法 都只是符号引用,即只是个符号,知道方法名字, 但是不知道方法的实际指令运行地址
符号引用如下,不过我这展示的时class_info即类的符号引用, 实际上还会有method_info即方法的引用:

然后方法在class文件中时这样存放的, 先是一个method_count数量,接着再存储方法。

此时是不知道方法的指令地址的。 除非从符号引用转为直接引用。

Q:什么时候方法的符号引用会转为实际方法区中的直接引用?
A:类加载的解析阶段会把满足「编译期可知,运行期不可变」的方法的符号引用替换为指向方法区的直接引用,不会延迟到运行时再去完成。

  • 构造
  • 私有
  • 静态
  • final修饰

上面这4类方法在类加载时都会被识别出来,并转成 指向方法区的直接引用(即能知道了指令地址了,而不是字节码的符号)

Q:动态分派(即多态), 虚拟机里是怎么确定调用哪个方法的?
如下, 他怎么确定调用的是Son实现的do, 还是father实现的do?

int a = 1;
Father f = new Son()
f.do(a);

A:首先,通过静态分派, 他知道一定选用的是f(int a) 这个方法,但是他不知道选用哪个类的do(int a)方法。
而你执行f.do(a)时, 操作数栈上会存放一个对象引用

那么执行f方法的虚拟机指令就会通过这个对象引用,找到他的实际类型的class

他会在这个实际类中查找是否有实现这个方法,具体看class文件中有没有这个方法的定义

如果没有找到,他就去父类找,父类的关系class文件中就可以知道

如果父类没有,就接着往上找,直到找到实现了的。

本文分享自华为云社区《Java知识点问题精选之类、接口、枚举》,原文作者:breakDraw 。

点击关注,第一时间了解华为云新鲜技术~

先收藏!关于Java类、接口、枚举的知识点大汇总的更多相关文章

  1. Java类/接口的API

    本章节收集的类/接口API有: Object类,枚举,包装类,接口Comparable,类Arrays,异常, Object类 public String toString(): [把一个对象的信息用 ...

  2. 30K以上的高薪Java程序员所需技能大汇总

    总所周知,Java是目前使用最为广泛的网络编程语言之一. 它具有简单,面向对象,稳定,与平台无关,解释型,多线程,动态等特点. 一般的JAVA程序员或许只需知道一些JAVA的语法结构就可以应付了.但要 ...

  3. Java 基础 enum枚举类 的创建/使用/接口继承 ,以及手动创建枚举类的对象为:public static final

    笔记: import java.lang.*; /**一:枚举类 : enum Season implements info { s1(),s2(),s3(),s4() }; //s1--s4 放在S ...

  4. Java笔记:枚举类

    1.一个类的实例是有限且固定的,这个类称为枚举类.比如季节类,只有四个对象(春.夏.秋.冬) 2.手动实现一个枚举类(1)通过private将构造器隐藏起来(2)把这个类的所有可能实例都使用priva ...

  5. JAVA(四)类集/枚举

    成鹏致远 | lcw.cnblog.com |2014-02-04 JAVA类集 1.认识类集 类集的作用 类集实际上就是一个动态的对象数组,与一般的对象数组不同,类集中的对象内容可以任意扩充 类集的 ...

  6. Java 类、接口的API

    本章节收集的类/接口API有: Object类,枚举,包装类,接口Comparable,类Arrays,Thread类,System类,Math,BigInteger,Random,日期时间,异常 O ...

  7. Java学习笔记-枚举类

    实例有限且固定的类成为枚举类 枚举类的实现 早期时候的实现形式: public static final int SEASON_SPRING = 1; public static final int ...

  8. 【Java基础】枚举类与注解

    枚举类与注解 枚举类的使用 当需要定义一组常量时,强烈建议使用枚举类. 枚举类的理解:类的对象只有有限个,确定的. 若枚举只有一个对象, 则可以作为一种单例模式的实现方式. 枚举类的属性: 枚举类对象 ...

  9. 规则引擎集成接口(九)Java类对象

    Java类对象 右键点击“对象库” —“添加java类对象”,如下图: 弹出窗体,在文本框中输入类的全名“com.flagleader.test.Test”,选择该类型后确定,如下: 显示如下,勾选上 ...

  10. 规则引擎集成接口(七)规则引擎调用Java类

    规则引擎调用Java类 通过myEclipse编写一个简单工程,其中方法是两数相加等到结果,既结果1=输入值1+输入值2.实现规则调用外部接口的方法有三种. 1:接口实例:在myEclipse中制作一 ...

随机推荐

  1. 14.9 Socket 高效文件传输

    网络上的文件传输功能也是很有必要实现一下的,网络传输文件的过程通常分为客户端和服务器端两部分.客户端可以选择上传或下载文件,将文件分块并逐块发送到服务器,或者从服务器分块地接收文件.服务器端接收来自客 ...

  2. P7072 [CSP-J2020] 直播获奖

    Problem 考查知识点:桶优化. 题目简述 竞赛的获奖率为 \(w\%\),即当前排名前 \(w\%\) 的选手的最低成绩就是即时的分数线. 若当前已评出了 \(p\) 个选手的成绩,则当前计划获 ...

  3. 一文讲透DevOps理论体系的演进

    一.前言 当前,我国处于以信息化.数字化.网络化.智能化为特征的科技变革浪潮中,企业数字化转型大势所趋,那么作为支撑企业IT运转的运营体系也在向多元方向发展,比如DevOps(研发运营一体化).AIO ...

  4. Net 高级调试之五:如何在托管函数上设置断点

    一.简介 今天是<Net 高级调试>的第五篇文章.今天这篇文章开始介绍如何在托管方法和非托管方法设置断点,我们要想调试程序,必须掌握调试的一些命令,动态调试的命令,我们在上一篇文章已经讲过 ...

  5. EFCore 使用FluntApi配置 全局查询筛选器

    我们在类中通常会有一个属性为 IsDel来表示软删除或也称逻辑删除,这个属性会导致我们在进行查询操作时,每一次都要 .where(s=>s.IsDel==false) 非常的麻烦.在使用efCo ...

  6. C#判断字符串的显示宽度

    C#判断字符串的显示宽度 起因: 公司有一个使用项目使用HTML转换为PDF,其中有一个表格,表格的最后一列中的单元格,其字符串超长后会被丢弃,而不是换行到下一行展示(HtmlToPdf渲染引擎导致的 ...

  7. 使用 LCM LoRA 4 步完成 SDXL 推理

    LCM 模型 通过将原始模型蒸馏为另一个需要更少步数 (4 到 8 步,而不是原来的 25 到 50 步) 的版本以减少用 Stable Diffusion (或 SDXL) 生成图像所需的步数.蒸馏 ...

  8. Springboot 自动发送邮件

    完成Springboot配置发件邮箱,自动给其他邮箱发送邮件功能 一.创建springboot基础项目,引入依赖 <!-- Spring Boot 邮件依赖 --> <depende ...

  9. 文心一言 VS 讯飞星火 VS chatgpt (146)-- 算法导论12.2 1题

    一.用go语言,假设一棵二叉搜索树中的结点在1到 1000 之间,现在想要查找数值为 363 的结点.下面序列中哪个不是查找过的序列? a.2,252,401,398,330,344,397,363. ...

  10. 地图选择器datav怎么使用?

    DataV 是一款基于阿里云的数据可视化产品,它提供了丰富的组件和功能,其中包括地图选择器.下面是一个详细的介绍: 1. 了解 DataV: - DataV 是一款强大的数据可视化工具,能够帮助用户将 ...