Java类和对象面试问题总结2

1.谈谈你对static关键字的理解?

1.1static的特点

(1)static是修饰符,用于修饰成员。

(2)static修饰的成员被所有对象所共享。

(3)static优于对象存在,因为static修饰的成员已经随着类的加载已经存在了。

(4)static修饰的成员多了一种调用方式,可以直接被类名所调用,类名.静态成员。

(5)static修饰的成员是共享数据,对象中的存储是特有数据。

1.2static变量

(1)按照是否静态对类成员变量进行分类,一种是被static修饰的成员变量,叫静态变量或者类变量,一种是没有被static修饰的变量,叫做实例变量。

区别:静态变量在内存中只有一个拷贝,JVM只为静态分配一次内存,在过类加载的过程完成静态变量的内存分配。可类名.静态成员直接访问,也可以通过对象来访问(不推荐)

           实例变量,每创建一个实例,就会为实例变量分配一次内存,内存中实例变量可以在内存中存在多个拷贝,但互不影响。

(2)static成员变量的初始化按照定义的顺序进行初始化,static不能修饰局部变量。

(3)以下两种情况使用静态变量。

   在对象之间共享值时;

   方便访问变量时; 

1.3静态方法

静态方法不用生成类的实例就可以直接调用,即static修饰的成员不在归所对象所有,而是属于类,可以理解为共享的,可以通过

类名直接访问,不用消耗资源反复创建对象,因为在类加载的时候已经在内存中,直到程序结束才会被内存释放,没有用static修饰的成员在使用完后就会被内存回收。

1.4static修饰类

一般静态内部类可以用static修饰,(静态内部类一般可以分为四种:常规内部类、静态内部类、局部内部类、匿名内部类),只能访问外部类的static成员,不能直接访问外部类的实例方法和实例变量。

1.5static代码块

  static静态代码块在类中独立于类成员的static语句块,可以有多个,位置随便放,不在任何的方法体内,JVM在加载类的时候会执行这些语句块,如果有多个,会按照顺序执行,每个代码块被执行一次,可以用来优化程序性能。

1.6static方法和Static代码块的区别

静态代码块是自动执行的

静态方法是被调用才执行的

静态方法只能直接调用同类的静态成员变量,不能访问类中的非静态成员变量。对于非静态成员变量和方法,只能通过创建类的实例对象来访问,而静态方法在使用前不需要创建任何对象(静态变量属于整个类,而不属于某个对象)

静态方法不能以任何方式调用this和super关键字,因为静态方法在使用前不创建任何实例对象,当静态方法调用时,this所引用的象对没有产生。(this关键字用来表示当前对象本身,或当前类的一个实例,通过this可以调用本对象的所有属性和方法,成员变量和方法内部的变量重名时,只能使用this)

2.谈谈类加载过程

类加载就是JVM把class文件加载到内存,并对数据校进行校验、准备、解析、初始化,最终形成JVM可以直接使用的类型的过程。

类加载的过程主要分为三部分:加载、链接、初始化。

链接又分为三个部分:验证、准备、解析。

2.1加载

把class字节码文件从各个源通过类加载器加载到内存中。

字节码文件来源:从本地路径下编译生成的.class文件,从jar包中的.class文件。从远程网络,以及动态代理实时编译。

类加载:一般包启括动类加载器、扩展类加载器、应用类加载器、用户的自定义类加载器。

启动类加载器:加载JAVA_HOME\jre\lib或-Xbootclasspath参数指定目录下的类库,我们无法获得启动类加载器,在Hotspot中,                  启动类加载器是JVM的一部分。所有其他类加载器都是独立于JVM之外的,并且需要启动类加载器加载。

扩展类加载器:负责加载JAVA_HOME\lib\jre\ext或者Java.ext.dirs系统变量指定目录下的类库。

应用类加载器:负责加载classpath下的类。

自定义加载器:防止代码反编译,对代码进行加密,自定义类加载器解密加密的代码。当字节码文件来自于不同源,通过自定义

                          类加载器从指定的来源加载类。

2.2链接

    将加载到JVM中的二进制字节流文件合并到JVM的运行状态中。包括验证、准备、解析。

(1)验证数据信息是否符合JVM规范。是否是有效的字节码文件,验证内容包含类数据信息的格式验证、语义分析、验证操作。

格式验证:验证是否符合class文件规范。

语义验证:验证是否有被final修饰的类被继承。类中的final方法是否被子类重写。子类和父类是否有冲突,出现不合理的重载。

操作验证:在操作数栈中的数据必须进行正确的操作,对常量池中的各种符号引用执行验证。

(2)准备

准备为类变量即静态变量分配内存,赋予初值(实例变量还没产生对象,不包括)。初始值不是代码中具体写的初始化的值,而是Java虚拟机根据不同变量类型默认的初始值。final修饰的静态变量直接赋予原值。

(3)解析

将常量池中的符号引用转换为直接引用。

符号引用:一个字符串,能够唯一识别一个类、一个方法、一个变量的相关信息。

直接引用:可以理解为一个内存地址,偏移量。例如一个类、方法、字段在内存中的指针和偏移量。

一些静态绑定的会被解析。静态绑定包括final方法、static方法、构造器。动态绑定的在运行的时候才会解析。

2.3初始化

对类变量进行初始化的,执行类构造器的过程。

其实是对static修饰的变量和语句进行初始化。

初始化一个类,按照父类子类顺序初始。

同时存在多个静态变量和静态代码块,按顺序从上向下执行。

3.为什么要有类加载器?自定义类加载器如何实现?

3.1为什么要有类加载器

类加载器就是负责把Java类中的字节码文件加载到虚拟机中

3.2自定义类加载器如何实现

自定义的类加载器只需要继承ClassLoader,并覆盖findClass方法即可。

4.什么是双亲委派模型?为什么要遵循双亲委派模型?

4.1 双亲委派模型

     如果一个类加载器收到加载类的请求,他首先不会自己自己尝试加载这个类,而是把加载请求委派给父类加载器完成,每个类加载器都是如此,只有当父类加载器在自己的搜索范围内找不到加载的类时,子类加载器才会尝试自己去加载这个类。

4.2 原因

(1)安全,避免用户自己编写的动态类替换Java的核心类。

(2)避免类重复加载。JVM区分不同类,不仅仅根据类名(类加载实例+包名+类名),相同的类文件被不同的类加载器加载就是不同的两个类。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值