9个Java初始化和回收的面试题

Java的初始化和回收相关知识是公司在面试开发人员时常考察的问题,这里列出了8大常见的题型。


1.Java中是如何区分重载方法的?

通过重载方法的参数类型和顺序来进行区分的。

注意:若参数类型和顺序均相同时,不管参数名是否相同,编译器均会报错,提示方法已经被定义。且不能根据返回值类型来区分,如果根据返回值来区分的话,有时程序里调用方法时并不需要返回值,那么程序都无法确定该调用那个重载方法。

2.阅读以下程序,解释其中的错误。


  1. public static void testLong(long i) { 
  2.         System.out.println("test long"); 
  3.     } 
  4.      
  5.     public static void testFloat(float i) { 
  6.         System.out.println("test float"); 
  7.     } 
  8.     public static void main(String[] args) { 
  9.         testLong(50); 
  10.         testFloat(1.5); 

testLong没有
问题,因为传递的参数50是int型的,而接收方参数是long型的,小范围可以自动转型为大范围的数据类型;testFloat不会通过编译,因为传递

的参数1.5是double类型的,而接收方参数是float类型的,大范围转型为小范围数据类型需要显式转换,即改为testFloat(1.5f)。

3.阅读以下程序,解释其中的错误。


  1. public static class A { 
  2.         A(int i) { 
  3.             System.out.println("A(int i)"); 
  4.         } 
  5.     } 
  6.     public static void main(String[] args) { 
  7.         A a = new A(); 

在定义了自定义构造器后,若要使用默认构造器,则需要显式指定默认构造器,否则A a = new A();不能编译通过。

4.阅读以下程序,解释其中的错误


  1. public static class A { 
  2.         A() { 
  3.             System.out.println("A()"); 
  4.         } 
  5.         A(int i) { 
  6.             System.out.println("A(int i)"); 
  7.         } 
  8.         A(int i, int j) { 
  9.             A(); 
  10.             A(i); 
  11.             System.out.println("A(int i, int j)"); 
  12.         } 

在一个构造器中调用其它构造器时,需要使用this关键字进行调用,如this();在一个构造器中可调用仅一个其它构造器,并且调用其它构造器的语句需放在调用者(即发出调用行为的构造器)语句块的第一行。

5.阅读以下程序,写出执行结果。


  1. public static class A { 
  2.         private int i; 
  3.         private String j; 
  4.         int getI() { 
  5.             return i; 
  6.         } 
  7.         String getJ() { 
  8.             return j; 
  9.         } 
  10.         A(int i) { 
  11.             i = i; 
  12.         } 
  13.         A(String j) { 
  14.             this.j = j; 
  15.         } 
  16.     } 
  17.     public static void main(String[] args) { 
  18.         System.out.println(new A(5).getI()); 
  19.         System.out.println(new A("hello").getJ()); 

执行结果为:

0

hello

对于i = i;这个语句而言,它并未改变实例变量i的值,且i的默认值为0,因此结果也为0,若需要改变实例变量i的值,需要改为this.i = i;

6.在一个类中,声明了若干个static方法和非static方法,请谈谈声明的static方法是否能访问声明的非static方法,说明理由?

static方法不能访问非static方法,因为static方法是属于这个类本身的一个方法,在编译期间就已经确定了;而非static方法是属于这个类的对象的方法,需要在实例化之后才能访问到。若在static方法中访问非static方法,将不能通过编译。

7.static关键字为何不能修饰局部变量?

static
关键字修饰的变量或方法是属于类的,在编译时就已经确定了;而普通变量或方法是属于该由类生成的对象,需要在实例化后才能确定。因此,若static关键
字修饰了方法的局部变量,一方面方法需要在实例化之后才能确定,另一方面static修饰的变量需要在编译时确定,这就会导致矛盾。

8.finalize()有何用途?什么情况下需要调用这个函数?

在需要释放内存的地方调用finalize(),则在下一轮垃圾回收时会回收占用的内存,一般情况下不需要显式调用此函数。


圾回收器只能回收那些由new关键字创建的对象所占用的内存,那么有些不是通过这种方式(比如调用C++本地方法)所占用的内存如何回收呢?那么就需要使

用finalize()了。由于C++中需要使用free()函数来释放内存,所以Java程序在调用C++时需要调用finalize()方法来释放内
存。

9.列出并简要解释几种常见垃圾回收技术。

引用计数:每个对象都包含了一个引用计数器,每被引用一次,计数器都加1,引用者被置为null或者销毁,计数器就减1。垃圾收集器进行轮询,一旦发现计数器的值小于1,就回收该对象占用的内存。

停止复制:在垃圾回收机制运行时,程序需要停止运行,将每个活动的对象由一个堆转移到另一个堆,留下的垃圾会被回收。

标记清除:从堆栈和静态存储区域开始,寻找到活的对象就对其进行标记,所有的标记过程完成后,就对垃圾进行回收。

来源:51CTO

时间: 2024-08-25 06:09:10

9个Java初始化和回收的面试题的相关文章

java学习笔记4--对象的初始化与回收

1.对象初始化和回收 对象初始化 系统在生成对象时,会为对象分配内存空间,并自动调用构造方法对实例变量进行初始化 对象回收 对象不再使用时,系统会调用垃圾回收程序将其占用的内存回收 构造方法 一种和类同名的特殊方法 用来初始化对象 Java中的每个类都有构造方法,用来初始化该类的一个新的对象 没有定义构造方法的类,系统自动提供默认的构造方法 构造方法的特点 方法名与类名相同 没有返回类型,修饰符void也不能有 通常被声明为公有的(public) 可以有任意多个参数 主要作用是完成对象的初始化工

深入理解Java之垃圾回收

概述 由于JVM中垃圾收集器的存在,使得Java程序员在开发过程中可以不用关心对象创建时的内存分配以及释放过程,当内存不足时,JVM会自动开启垃圾收集线程,进行垃圾对象的回收. 那么垃圾回收线程到底是什么时候触发,并如何实现垃圾回收的呢?本文将对openjdk的源码进行分析,并通过代码分析Java垃圾回收的过程. VMThread VMThread主要负责调度执行虚拟机内部的VM线程操作,如GC操作等,在JVM实例创建时进行初始化. VMThread::create() VMThread::cr

Java的垃圾回收机制研究

一.谁在做Garbage Collection? 一种流行的说法:在C++里,是系统在做垃圾回收;而在Java里,是Java自身在做. 在C++里,释放内存是手动处理的,要用delete运算符来释放分配的内存.这是流行的说法.确切地说,是应用认为不需要某实体时,就需用delete告诉系统,可以回收这块空间了.这个要求,对编码者来说,是件很麻烦.很难做到的事.随便上哪个BBS,在C/C++版块里总是有一大堆关于内存泄漏的话题. Java采用一种不同的,很方便的方法:Garbage Collecti

局部变量-关于java内存垃圾回收的一点疑问

问题描述 关于java内存垃圾回收的一点疑问 class test{ void m(){ Object obj[]=new Object[1]; Object o = new Object(); obj[0]=o; o = null;//用不着 } } 很常见的一个例子,说最后Object对象都没有被释放,因为obj[0]还引用这个对象. 我的疑问是,既然局部变量在方法运行完,引用会被销毁,也就是说o不用被置为null,也会堆内存的Object对象也会被回收(符合回收的条件,不一定立即GC),那

java 初始化-Java类的初始化顺序问题

问题描述 Java类的初始化顺序问题 一般在Java对象能够调用方法之前,此类中的成员变量就已经初始化完毕,那如果这个成员是匿名内部类呢?也会等到这个匿名内部类中的代码全部跑完吗? 解决方案 Java初始化顺序1在new B一个实例时首先要进行类的装载.(类只有在使用New调用创建的时候才会被java类装载器装入)2,在装载类时,先装载父类A,再装载子类B3,装载父类A后,完成静态动作(包括静态代码和变量,它们的级别是相同的,安装代码中出现的顺序初始化)4,装载子类B后,完成静态动作类装载完成,

java中有垃圾回收GC, 为什么还要调用close

问题描述 比如说流操作结束后,为什么一定要close掉.java有垃圾回收器,这样做不就是多此一举吗.? 解决方案 解决方案二:自己顶一下解决方案三:因为java的垃圾回收,用户是没有办法控制的,它会在不确定的时候触发,而且java不保证在整个程序运行期一定会触发垃圾回收,所以对于流.socket等之类的资源用完之后一定要关闭.而且垃圾回收机制对于socket.thread之类的对象即使引用计数为0了,只要还是在活动的情况下,也不会被回收.解决方案四:垃圾回收机制对于socket.thread之

java对象转化-有时候我发现java初始化的一个对象不用new关键词的哦

问题描述 有时候我发现java初始化的一个对象不用new关键词的哦 是不是用get╳╳方法就可以得到一个对象,或者初始化一个对象呢,有时候我发现java初始化的一个对象不用new关键词的哦 解决方案 new的过程是在java虚拟机中分配内存地址,也就是分配地盘给你,如果你没有立足之地你怎么做其他事情.在spring框架中是已经帮你new好了,直接等你使用,这样可以提高效率.get/set方法只是获取值和赋值的方法而已. 解决方案二: get是封装过的 其实里边还是在new,只是你看不到.单利模式

Java 的垃圾回收机制(转)

先看一段转载,原文出自 http://jefferent.iteye.com/blog/1123677 虚拟机中的共划分为三个代:年轻代(Young Generation).年老点(Old Generation)和持久代(Permanent Generation).其中持久代主要存放的是Java类的类信息,与垃圾收集要收集的Java对象关系不大.年轻代和年老代的划分是对垃圾收集影响比较大的. 年轻代: 所有新生成的对象首先都是放在年轻代的.年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象.

简单理解Java的垃圾回收机制与finalize方法的作用_java

垃圾回收器要回收对象的时候,首先要调用这个类的finalize方法(你可以 写程序验证这个结论),一般的纯Java编写的Class不需要重新覆盖这个方法,因为Object已经实现了一个默认的,除非我们要实现特殊的功能(这 里面涉及到很多东西,比如对象空间树等内容). 不过用Java以外的代码编写的Class(比如JNI,C++的new方法分配的内存),垃圾回收器并不能对这些部分进行正确的回收,这时就需要我们覆盖默认的方法来实现对这部分内存的正确释放和回收(比如C++需要delete). 总之,f