Java面试题(六)

1. 静态内部类和内部类有什么区别

什么是内部类呢?简单的说就是在一个类的内部又定义了一个类,这个类就称之为内部类(Inner Class)。

内部类的特点:

内部类可以访问其所在类的属性(包括所在类的私有属性),内部类创建自身对象需要先创建其所在类的对象,看一个例子:

public class Out {
	private int num	=100;
	public class Inner{
		private int num	=200;
		public void paint() {
			int num=500;
			//执行本方法中的属性
			System.out.println(num);
			//执行本类的属性
			System.out.println(this.num);
			//执行外部类的属性
			System.out.println(Out.this.num);
		}
	}
			public static void main(String args[]) {
			//内部类创建自身对象需要先创建其所在类的对象
			Out out=	new Out();
			Out.Inner in=out.new Inner();
			in.paint();
			}
}

区别

1.静态内部类不需要有指向外部类的引用。但非静态内部类需要持有对外部类的引用。

2.静态内部类可以有静态成员(方法,属性),而非静态内部类则不能有静态成员(方法,属性)。 

3.静态内部类不能访问外部类的非静态成员,只能访问外部类的静态成员。 非静态内部类能够访问外部类的静态和非静态成员。

实例化方式不同:

1.静态内部类:不依赖于外部类的实例,直接实例化内部类对象 

2. 非静态内部类:通过外部类的对象实例生成内部类对象 

2.反射的概念与作用

反射的概念:

反射,一种计算机处理方式。是程序可以访问、检测和修改它本身状态或行为的一种能力。

  • 程序在运行状态中, 可以动态加载一个只有名称的类, 对于任意一个已经加载的类,都能够知道这个类的所有属性和方法; 对于任意一个对象,都能调用他的任意一个方法和属性
  • 加载完类之后, 在堆内存中会产生一个Class类型的对象(一个类只有一个Class对象), 这个对象包含了完整的类的结构信息,而且这个Class对象就像一面镜子,透过这个镜子看到类的结构,所以被称之为:反射.
  • java反射使得我们可以在程序运行时动态加载一个类,动态获取类的基本信息和定义的方法,构造函数,域等。
  • 反射使java这种静态语言有了动态的特性。

反射的作用:

通过反射可以使程序代码访问装载到JVM 中的类的内部信息

  1. 获取已装载类的属性信息 
  2. 获取已装载类的方法
  3. 获取已装载类的构造方法信息

3.Java中参数的传递

Java中参数的传递有两种

一种是按值传递(call by value:传递的是具体的值,如基础数据类型)

另一种是按引用传递(call by reference:传递的是对象的引用,即对象的存储地址)。

前者不能改变实参的数值,后者虽然不能改变实参的参考地址,但可以通过该地址访问地址中的内容从而实现内容的改变

4.存在使i+1<i的数么? 

存在, byte , int 等的的最大值, 加1后变为负数. 

public class Test {
    public static void main(String[] args) {
        byte a = 127;
        byte b = (byte) (a+1);
    System.out.println(a+"\t"+b);
    }
}
//输出结果
127 -128

5.接口可否继承接口?抽象类是否可实现接口?抽象类是否可继承实体类?

接口可以继承接口
抽象类可以实现接口
抽象类可以继承实体类。 

6.int与Integer有什么区别?

int是java提供的8种原始数据类型之一。

Java为每个原始类型提供了封装类,Integer是java为int提供的封装类。

int的默认值为0,而Integer的默认值为null

int则无法表达出未赋值的情况,例如,要想表达出没有参加考试和考试成绩为0的区别,则只能使用Integer。

7.可序列化对象为什么要定义serialversionUID值?

什么是 serialVersionUID ?

  • 顾名思义,serialVersionUID是序列化版本号
  • 所有可序列化的类,都有一个静态serialVersionUID属性;如果我们没有显示定义serialVersionUID,IDE默认提供一个serialVersionUID

serialVersionUID 有什么用 ?

  • serialVersionUID 用来标识一个可序列化类的版本
  • 当我们序列化一个对象时,会将 serialVersionUID 一并写出
  • 当我们反序列化一个对象时,会将读入的serialVersionUID与当前类的serialVersionUID作比较。如果相同,则反序列化成功;如果不同,则反序列化失败

总结

SerialVersionUid,简言之,其目的是序列化对象版本控制,有关各版本反序列化时是否兼容
如果在新版本中这个值修改了,新版本就不兼容旧版本,反序列化时会抛出InvalidClassException异常。
如果修改较小,比如仅仅是增加了一个属性,我们希望向下兼容,老版本的数据都能保留,那就不用修改;
如果我们删除了一个属性,或者更改了类的继承关系,必然不兼容旧数据,这时就应该手动更新版本号,即SerialVersionUid。
说白了就是为了一个兼容性判断

8.十进制数72转换成八进制数是多少?

110

public class Test {
    public static void main(String[] args) {
    //10进制转2进制
    System.out.println(Integer.toBinaryString(72));
    //10进制转16进制
    System.out.println(Integer.toHexString(72));
    //10进制转8进制
    System.out.println(Integer.toOctalString(72));
    }
}
//输出
1001000
48
110

9.Java程序中创建新的类对象,使用关键字new,回收无用的类对象使用关键字free正确么?

Java程序中创建新的类对象,使用关键字new是正确的; 回收无用的类对象使用关键字free是错误的

垃圾回收机制回收任何对象之前,总会先调用它的finalize方法(如果覆盖该方法,让一个新的引用变量重新引用该对象,则会重新激活对象)。
程序员可以通过System.gc()或者Runtime.getRuntime().gc()来通知系统进行垃圾回收,会有一些效果,但是系统是否进行垃圾回收依然不确定。 

10.Class类的getDeclaredFields()方法与getFields()的区别?

getDeclaredFields(): 可以获取所有本类自己声明的方法, 不能获取继承的方法
getFields(): 只能获取所有public声明的方法, 包括继承的方法

 

posted @ 2022-05-16 22:01  卷心菜-小白  阅读(158)  评论(0)    收藏  举报