📖 Java Basic Knowledge——第一天
若有定义语句: int a=10 ; double b=3.14 ; 则表达式 ‘A’+a+b 值的类型是()
📚 解析:选C,double类型,因为按照类型大的与类型小的运算,强制转换类型小的进行运算的规则,double>int>char,因此结果是double类型。
关键字super的作用是?
- 用来访问父类被隐藏的非私有成员变量
- 用来调用父类被重写的方法
- 用来调用父类的构造函数
程序解答
static boolean foo(char c){
System.out.print(c);
return true;
}
public static void main(String[] args) {
int i =0;
for(foo('A');foo('B')&&(i<2);foo('C')){
i++;
foo('D');
}
}
📚 解析
1️⃣ 其实foo(‘A’);就是初始化条件,只会执行一次,所以第一个打印的肯定是A
2️⃣ 因为i=0;循环条件是i<2 (由此可知循环i等于2的时候就会停止循环,)所有0<2满足条件,接着会输出B,然后执行i++;i就变成1了,再输出D,再最后输出C,一次循环后的结果是:ABDC
3️⃣ 第二次循环的开始是foo(‘A’);是初始条件所以不会执行,直接从foo(‘B’)开始,输出B,然后i为1,且小于2,此时循环体内再次执行i++;i的值为2了,再次输出D,最后输出C
第二次循环输出:BDC
4️⃣ *然后循环再次执行for(foo(‘A’);foo(‘B’)&&(i<2);foo(‘C’))
直接输出B,***i的值在第二轮循环后的值变成了2,2<2不成立,终止循环,输出B
下面关于Spring的说法中错误的是()
📚 解析: Spring并没有为我们提供日志系统,我们需要使用AOP(面向方面编程)的方式,借助Spring与日志系统log4j实现我们自己的日志系统。
程序解答题
public class MyClass {
long var;
public void MyClass(long param) { var = param; }//(1)
public static void main(String[] args) {
MyClass a, b;
a =new MyClass();//(2)
b =new MyClass(5);//(3)
}
}
编译错误将在(3)处发生,因为该类没有构造函数,该构造函数接受一个int类型的参数
哪段程序能够正确的实现了GBK编码字节流到UTF-8编码字节流的转换
dst=new String(src,"GBK").getBytes("UTF-8")
📚 解析:先通过GBK编码还原字符串,在该字符串正确的基础上得到“UTF-8”所对应的字节串
程序解答
String str = ``""``;
System.out.print(str.split(``","``).length);
📚 解析:String split 这个方法默认返回一个数组, 如果没有找到分隔符, 会把整个字符串当成一个长度为1的字符串数组
程序解答题
public class Base
{
public void methodOne()
{
System.out.print("A");
methodTwo();
}
public void methodTwo()
{
System.out.print("B");
}
}
public class Derived extends Base
{
public void methodOne()
{
super.methodOne();
System.out.print("C");
}
public void methodTwo()
{
super.methodTwo();
System.out.print("D");
}
}
ABDC
程序解答题
import java.util.Date;
public class SuperTest extends Date{
private static final long serialVersionUID = 1L;
private void test(){
System.out.println(super.getClass().getName());
}
public static void main(String[]args){
new SuperTest().test();
}
}
📚 解析:TestSuper和Date的getClass都没有重写,他们都是调用Object的getClass,而Object的getClass作用是返回的是运行时的类的名字。这个运行时的类就是当前类,所以
super.getClass().getName()
返回的是test.SuperTest,与Date类无关
要返回Date类的名字需要写super.getClass().getSuperclass()
程序代码题
枚举类在后台实现时,实际上是转化为一个继承了java.lang.Enum类的实体类,原先的枚举类型变成对应的实体类型,上例中AccountType
变成了个class AccountType
,并且会生成一个新的构造函数,若原来有构造函数,则在此基础上添加两个参数,生成新的构造函数,如上例子中:
private AccountType(){ System.out.println(“It is a account type”); }
会变成:
private AccountType(String s, int i){
super(s,i); System.out.println(“It is a account type”);
}
而在这个类中,会添加若干字段来代表具体的枚举类型:
public static final AccountType SAVING;
public static final AccountType FIXED;
public static final AccountType CURRENT;
而且还会添加一段static代码段:
static{
SAVING = new AccountType("SAVING", 0);
... CURRENT = new AccountType("CURRENT", 0);
$VALUES = new AccountType[]{
SAVING, FIXED, CURRENT
} }
以此来初始化枚举中的每个具体类型。(并将所有具体类型放到一个$VALUE数组中,以便用序号访问具体类型)
📚 小结:在初始化过程中new AccountType
构造函数被调用了三次,所以Enum
中定义的构造函数中的打印代码被执行了3遍。
final 的理解
A.final修饰方法后,方法是不可被重写的,因为它已经是“最终形态”了。但不会影响重载
B.final修饰类标志此类不可被继承。如果final可以标志抽象类和接口,抽象类不能继承?接口不准实现?
那还要来什么意义,所以final不能修饰抽象类和接口
C.题目中这个也字就是来误导人的,同A一样解释过了,final修饰的方法不可重写
D.这道题不能太钻牛角尖,final确实是修饰变量,只不过被修饰过的变量不能再变了,既然变量不能再变了我们就可以把它当做常量。
Java 类加载 ClassLoader 知识理解
JDK中提供了三个ClassLoader,根据层级从高到低为:
- Bootstrap ClassLoader,主要加载JVM自身工作需要的类。
- Extension ClassLoader,主要加载%JAVA_HOME%\lib\ext目录下的库类。
- Application ClassLoader,主要加载Classpath指定的库类,一般情况下这是程序中的默认类加载器,也是ClassLoader.getSystemClassLoader() 的返回值。(这里的Classpath默认指的是环境变量中配置的Classpath,但是可以在执行Java命令的时候使用-cp 参数来修改当前程序使用的Classpath)
⭐ JVM加载类的实现方式,我们称为 双亲委托模型:
如果一个类加载器收到了类加载的请求,他首先不会自己去尝试加载这个类,而是把这个请求委托给自己的父加载器,每一层的类加载器都是如此,因此所有的类加载请求最终都应该传送到顶层的Bootstrap ClassLoader中,只有当父加载器反馈自己无法完成加载请求时,子加载器才会尝试自己加载。
双亲委托模型的重要用途是为了解决类载入过程中的安全性问题。
假设有一个开发者自己编写了一个名为Java.lang.Object的类,想借此欺骗JVM。现在他要使用自定义ClassLoader来加载自己编写的java.lang.Object类。然而幸运的是,双亲委托模型不会让他成功。因为JVM会优先在Bootstrap ClassLoader的路径下找到java.lang.Object类,并载入它