Java面试题总结(一)

折磨人的小妖精---main方法

真的有公司会这么变态,用main方法来折磨你吗?你得承认,的确有比较low的公司会这么做。本文对这些与main方法相关的问题做一个小结。

1、下列程序运行结果是
public class Hello {
    public static void main(String s) {
        System.out.println("Hello");
    }
}
A.编译错误
B.运行输出 "Hello"
C.编译无错,但运行时指示没有定义构造方法
D.编译无错,但运行时指示没有正确定义main方法

编译器只检查语法问题(包括检查异常,Checked Exception),如果没有语法问题,编译器会将源程序编译成字节码文件,由虚拟机在运行时对字节码进行解读,如果运行时程序无法正常工作,则JVM可能会抛出异常提示信息。

public static void main(String s),编译器检查其并没有任何语法错误,不过运行时会抛异常。

下面对main方法涉及到的知识点笼统地概括一下。

(1)访问权限(访问修饰词):只要符合语法规定的访问方法的权限,均能够通过编译。比如,private、默认、protectedpublic,都能通过编译器的检查。但是,运行时只有public不会被抛出异常,而且规定必须加public

(2)限定修饰词:只要是符合语法规范的限定修饰词,均能够通过编译。比如,abstract(此时所在类必须声明为abstract)、final、static、synchronized、native,都能够通过编译器的检查。但是,对于JVM而言,如果类中不存在static关键词是无论如何无法运行的。在static必须存在的情况下,可以加上final(表明不能被重写),synchronized(表明同步),这两个在运行时均正常,不抛异常信息。不过,在static存在的情况下加abstractstatic不存在时如果abstractfinal同时用也有问题),无法通过编译,原因是修饰词造成互相矛盾。

(3)返回值类型:只要符合语法规范的返回值类型均能够通过编译。注意到,如果是非void类型,必须加return语句;如果是void,可以加上return;,也可以不加。但是,只有void在运行时不抛异常,即使加上return;也不抛出异常。

(4)参数列表(参数类型,参数名):参数类型必须是String[],参数名只要是合法的标识符即可,不一定要写成args(约定俗称这么写,但Java语言规范没明确要求)。

针对这些知识点,下面列出相应的题目,仅供参考。

变式1:
public class Hello {
    private static void main(String[] s) {
        System.out.println("Hello");
    }
}
编译通过(会有警告,仍能通过编译),但运行时找不到main方法。

变式2:
public class Hello {
    public static int main(String[] s) {
        System.out.println("Hello");
        return 0;
    }
}
编译通过,但是运行时提示main方法返回值必须为空值型;
变式3:
public class Hello {
    public static void main(String 1$) {
        System.out.println("Hello");
    }
}
编译器检查到语法错误,无法通过编译。Java的标识符只能是字母、数字、下划线、美元符号组合,且不能以数字开头。当然变量名还能够是中文字符等,只不过我们不提倡。

变式4:
public class Hello {
    public static void main(String[] s) {
        System.out.println("Hello");
        return;  // 符合语法规范。void作为返回值时,可以使用return;使方法弹出栈帧。
    }
}
通过编译,运行时输出Hello

变式5:
public class Hello {
    public static final void main(String[] s) {  // final关键词表明main方法无法被子类覆盖
        System.out.println("Hello");
        return;
    }
}
通过编译,运行时输出:Hello

变式6:
public abstract class Hello {  // 抽象类允许其中有非抽象方法
    public static final void main(String[] $) {
        System.out.println("Hello");
        return;
    }
}
编译正确,运行时输出Hello

变式7:
import java.io.Serializable;

public abstract class Hello implements Cloneable, Serializable {
    public static final void main(String[] $) {
        System.out.println("Hello");
        return;
    }
}
编译正确,运行时输出Hello
分析:Cloneable,Serializable都是标记接口(Tagging Interface)

变式8:
import java.io.Serializable;

abstract class Hello implements Cloneable, Serializable {
    public static final void main(String[] $) {
        System.out.println("Hello");
        return;
    }
}编译正确,输出Hello分析:类的访问修饰符可以是public和默认两种,而且写在一起的多个类,至多只能有一个public类。

变式9:
public class Hello{
    static {
        System.out.print("Hello");
    }
    public static final void main(String[] $) {
     System.exit(0);
    }
    static {
        System.out.print(",World");
    }
}
编译正确,输出Hello,World。 注意:静态块在main方法调用之前载入。

变式10:
public class Hello{
    {
        System.out.println("Hello");
    }
    public static void main(String[] $) {
        System.exit(0);
    }
    static {
        System.out.println("world");
    }
}编译正确,输出world。 载入顺序:静态块,main方法(静态方法),普通块。但是在main方法时已经退出程序,因此普通块不执行。
变式11:public class Hello {
    public static synchronized void main(String[] 我) {
        System.out.println("Hello World");
        return;
    }
}编译正确,输出Hello World分析:允许在main方法中加入同步修饰词synchronized。Java语法没有规定不可以使用中文字符的,只是不推荐使用中文。

这里只是总结了部分关于main方法的注意点,还有许多细节内容没有总结到,比如不用main方法如何定义一个类?等等的问题。

《10个经典的Java main方法面试题》《不该被忽视的CoreJava细节(一)》



啰嗦一下:为什么main方法必须使用static关键词?

main方法实际上储存的位置是运行时常量池。在程序运行的时候,HelloWorld.class从运行时常量池被类装载器(ClassLoader)加载到虚拟机运行时常量池(方法区),然后再加载HelloWorld.class中需要导入的Java API和相应的静态资源。当核心类库API和除main外静态资源都加载完毕,虚拟机开始寻找HelloWorld.class中的main方法,如果成功找到需要的main方法,那么程序正是开始执行。

如果main方法不是static,那么虚拟机将无法构造运行时的诸多结构。因为运行时环境产生的前提是main方法正确加载,然后执行main方法中包含的内容。可以这么说,main方法是连接静态环境和运行时环境的桥梁。

本文关于main方法的内容几乎就是我所能找到的所有内容了,如果再要补充,获取只能够从底层字节码方面去研究了。这些都是将来的事,现在的确没有这么多闲工夫。

同现实的落差---记录心情

我所接收的教育、学习经历、性格秉性等等决定了我不喜欢教条主义(dogmatism)式的问题,而且有些东西不是说懂了就一定能在面试这种场合通过严密的逻辑向提问方展示。如果你想考验我是否懂了一个知识,可以以文章的形式告诉你我确实懂了,但是我很难接受人家非要在面试这种场合让我回答很书面化的内容。

比如,人家问我Override和Overload区别?我觉得我真的一时间无法回答完整,而且语言组织确实不行。但是如果是通过手写回答,我觉得可以答得很完美。

不管怎么说,只能去适应别人,适应社会的大潮,总不能让面试官来适应我吧,毕竟人家可能是技术大牛,而我只是菜鸟而已。

时间: 2024-10-15 11:54:24

Java面试题总结(一)的相关文章

Java面试题全集(中)

这部分主要是与Java Web和Web Service相关的面试题. 96.阐述Servlet和CGI的区别? 答:Servlet与CGI的区别在于Servlet处于服务器进程中,它通过多线程方式运行其service()方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于Servlet. 补充:Sun Microsystems公司在1996年发布Servlet技术就是为了和CGI进行竞争,Servlet是一个特殊的Java程

Java面试题下

这部分主要是开源Java EE框架方面的内容,包括hibernate.MyBatis.spring.Spring MVC等,由于Struts 2已经是明日黄花,在这里就不讨论Struts 2的面试题,如果需要了解相关内容,可以参考我的另一篇文章<Java面试题集(86-115)>.此外,这篇文章还对企业应用架构.大型网站架构和应用服务器优化等内容进行了简单的探讨,这些内容相信对面试会很有帮助. 126.什么是ORM?答:对象关系映射(Object-Relational Mapping,简称OR

java面试题及答案

JAVA相关基础知识1.面向对象的特征有哪些方面 1.抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节.抽象包括两个方面,一是过程抽象,二是数据抽象.2.继承:继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法.对象的一个新类可以从现有的类中派生,这个过程称为类继承.新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类).派

【福利 】Java面试题最全 (中)

这部分主要是与Java Web和Web Service相关的面试题. 阅读全文 更多: java,java学习,java面试题  http://techfoxbbs.com

【福利 】Java面试题最全 (下)

这部分主要是开源Java EE框架方面的内容,包括Hibernate.MyBatis.Spring.Spring MVC等,由于Struts 2已经是明日黄花,在这里就不讨论Struts 2的面试题 阅读全文 更多java,java学习,java面试题 http://techfoxbbs.com

Java面试题笔记

这是我从网上收集的常见Java面试题及答案,但只收录了我不会做的题目. 创建线程有几种不同的方式?你喜欢哪一种?为什么? 有三种方式可以用来创建线程: 继承Thread类 实现Runnable接口 应用程序可以使用Executor框架来创建线程池 实现Runnable接口这种方式更受欢迎,因为这不需要继承Thread类.在应用设计中已经继承了别的对象的情况下,这需要多继承(而Java不支持多继承),只能实现接口.同时,线程池也是非常高效的,很容易实现和使用. 在监视器(Monitor)内部,是如

JAVA面试题最全集

JAVA面试题最全集 2009-01-19 15:40 3458人阅读 评论(0) 收藏 举报 java面试ejbservletstringhashmap 一.Java基础知识1.Java有那些基本数据类型,String是不是基本数据类型,他们有何区别.2.字符串的操作:  写一个方法,实现字符串的反转,如:输入abc,输出cba  写一个方法,实现字符串的替换,如:输入bbbwlirbbb,输出bbbhhtccc.3.数据类型之间的转换  如何将数值型字符转换为数字(Integer,Doubl

一道java面试题-方法静态分派

一道面试题,下面程序的输出是? public class StaticDispatch { static abstract class Human{ } static class Man extends Human{ } static class Woman extends Human{ } public void sayHello(Human guy){ System.out.println("hello , guy!"); } public void sayHello(Man gu

10个经典的Java面试题

这里有10个经典的Java面试题,也为大家列出了答案.这是Java开发人员面试经常容易遇到的问题,相信你了解和掌握之后一定会有所提高.让我们一起来看看吧. 1.Java的HashMap是如何工作的? HashMap是一个针对数据结构的键值,每个键都会有相应的值,关键是识别这样的值. HashMap 基于 hashing 原理,我们通过 put ()和 get ()方法储存和获取对象.当我们将键值对传递给 put ()方法时,它调用键对象的 hashCode ()方法来计算 hashcode,让后

Java面试题精粹(基础知识)

本篇博文是自己针对网络上已出现的Java面试题帖子汇总,汇总并不是给出链接或直接转载内容,而是分析对比并整理出各帖子中常见.高频的面试题,这些经常露脸的面试题透出面试的趋势(为什么可以成为经典的面试题)及面试官的共通点.而作为求职者.技术爱好者的我们不仅要能够自信.精准得回答这些问题,更要知道为什么出这些问题,面试官想考察我们什么或希望我们给出怎样的回答,适当的再对回答进行拓展以达到更好的效果.面试本身包含了一些心理上的东西,面试官对于问题是有一个心中期许的答案,面试者若能够触摸到边缘或击中要害