关于java:先收藏关于Java类接口枚举的知识点大汇总

30次阅读

共计 3984 个字符,预计需要花费 10 分钟才能阅读完成。

摘要:Java 知识点精选之类、接口、枚举 30 问,算是比拟根底的,心愿大家一起学习提高。

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。

点击关注,第一工夫理解华为云陈腐技术~

正文完
 0