1、为什么JAVA代码可以实现一次编写、到处运行?
JVM(Java虚拟机)是Java代码跨平台的关键。在程序运行之前,Java源代码(.java)需要经过编译器编译成字节码(.class)。在程序运行之前,JVM负责将字节码翻译成特定平台下的机器码并运行,也就是说,只要在不同的平台上安装对应的JVM,就可以运行字节码文件。
同一份Java源代码在不同平台上运行,它不需要做任何改变,并且只需要编译一次,而编译好的字节码是通过JVM这个中间桥梁实现跨平台的,JVM是与平台相关的软件,它能将统一的字节码翻译成该平台的机器码。
注意事项:
1)编译的结果是生成字节码而不是机器码,字节码不能直接运行,必须通过JVM翻译成机器码才能运行;
2)跨平台的是Java程序而不是JVM,JVM使用C/C++开发的软件,不同平台下需要安装不同的版本。
2.一个Java文件里可以有多个类文件吗?
一个Java文件里可以有多个类,但最多只能有一个被public修饰的类;如果这个Java文件中包含public修饰的类,则这个类名必须和Java文件名一致。
3.说说对Java访问权限的了解
Java为我们提供了三种访问修饰符,即private、protected、public,在使用这些修饰符修饰目标时一共可以形成4中访问权限,即private、default、protected、public,注意在不加修饰符时为default访问权限。
在修饰成员变量或成员方法时:
private:该成员可以被该类内部成员访问;default:该成员可以被该类内部成员访问,也可以被同一包下其他的类访问;protected:该成员可以被该类内部成员访问,也可以被同一一包下其他的类访问,还可以被他的子类访问;pubic:该成员可以被任意包下任意类成员访问。
在修饰类时,该类只有两种访问权限:
default:该类可以被同一包下其他的类访问;public:该类可以被任意包下,任意的类访问。
4JAVA的数据类型
基本数据类型有8个,可以分为4小类,分别是整数类型(byte、short、int、long)、浮点类型(float、double)、字符类型(char)、布尔类型(boolean);引用类型就是对一个对象的引用,根据引用对象类型的不同,可以将引用类型分为3类,即数组、类、接口类型。引用类型本质上是通过指针指向堆中对象所持有的内存空间。
5.成员变量和局部变量的区别
成员变量:成员变量是在类的范围里定义的变量;成员变量有默认初始值;未被static修饰的成员变量也叫做实例变量,它存储于对象所在的堆内存中,生命周期与对象相同;被static修饰的成员变量也叫类变量,他存储于方法区中,生命周期与当前的类相同。
局部变量:局部变量是在方法里定义的变量;局部变量没有默认初始值;局部变量存储在栈内存中,作用的范围结束,变量空间会自动释放。
注意事项:Java中没有真正的全局变量,如果提到了全局变量,本意应指的就是局部变量。
6.为什么要有包装类?
Java语言是面向对象的语言,其设计理念是“一切皆对象”。但8种基本数据类型却出现了例外,他们不具备对象的特征。正是为了解决这个问题,Java为每一个基本数据类型都定义了一个对应的引用类型,这就是包装类。
7.自动装箱和自动拆箱的应用场景。
自动拆箱、自动装箱是JDK1.5提供的功能。自动装箱可以把一个基本类型的数据直接赋值给对应的包装类型;自动拆箱可以把一个包装类型的对象直接赋值给对应的基本类型。通过自动装箱、自动拆箱功能可以大大简化基本类型变量和包装类对象之间的转换过程。比如,某个参数类型为包装类型,调用时我们所持有的数据确实基本数据类型的值,则可以不做任何处理直接将这个基本类型的值传给对方即可。
8.如何对Integer和Double类型判断相等。
Integer和Double不可以直接进行比较,这包括:不能用==进行直接比较,因为他们是不同的数据类型;不能转换为字符串比较,因为转换为字符串后浮点值带小数点、整数值不带,这样他们永远不会相等;不能用compareTo方法比较,虽然他们都有compareTo方法,但该方法只能对相同类型进行比较。
整数、浮点类型的包装类都继承于Number类型,而Number类型分别定义了将数字转换为byte、short、int、long、float、double的方法。所以可以将Integer、Double先转换为相同的基本数据类型,然后用==进行比较。
Integer i = 100;
Double d = 100.00;
System.out.println(i.doubleValue() == d.doubleValue());
9.int和Integer有什么区别,二者在做==运算时会得到什么结果?
int是基本数据类型,Integer是int的包装类。二者在做==运算时,Integer会自动拆箱为int类型然后进行比较,此时弱国两个int值相等则返回true,否则返回false.
10.对面向对象的理解。
面向对象是一种更优秀的程序设计方法,他的基本思想是使用类、对象、继承、封装、消息等基本概念进行程序设计。他从现实世界中客观存在的事物出发来构造软件系统,并在系统构造中尽可能运用人类的自然思维方式,强调直接以现实世界种的事物为中心来思考认识问题,并根据这些事务的本质特征把他们抽象地表示为系统中的类,所谓系统的基本构成单元,这使得软件系统的组件可以直接映像到客观世界,并保持客观世界事务及其相互关系的本来面貌。
11.结构化程序设计的特点及其局限性
结构化程序设计方法主张按功能来分析系统需求,其主要原则可概括为自顶向下、逐步求精、模块化等。结构化程序设计首先采用结构化分析方法对系统进行需求分析,然后使用结构化设计方法对系统进行概要设计、详细设计,最后采用结构化编程方法来实现系统。
因为结构化程序设计主张按功能把软件系统逐步细分,因此这种方法也被称为面向功能的程序设计方法;结构化程序设计的每个功能都能负责对数据进行一次处理,每个功能都接受一些数据,处理完后输出一些数据,这种处理方式也被称为面向数据流的处理方式。
结构化程序设计里最小的程序单元是函数,每个函数都负责完成一个功能,用以接受一些输入数据,函数对这些输入数据进行梳理,处理结束之后输出一些数据。整个系统是由一个个函数组成,其中作为程序入口的函数被称为主函数,主函数一次调用其他普通函数,普通函数之间依次调用,从而完成整个软件系统的功能。
局限性:设计不够直观;适应性差,可扩展性不强。
12.面向对象的三大特征
面向对象的程序设计方法有三个基本特征:封装、继承、多态。封装指的是将对象的实现细节隐藏起来,然后通过一些公有方法来暴露该对象的功能;继承是面向对象实现软件复用的重要手段,当子类继承父类之后,子类作为一种特殊的父类将直接获得父类的属性和方法;多态指的是子类对象可以直接付给父类变量,但运行时依然表现出子类的行为特征,这意味着同一个类型的对象在执行同一个方法时可能表现出多种行为。
13.封装的目的是什么,为什么要有封装。
封装是面向对象编程语言对客观世界的模拟,在客观世界里,对象的状态信息都被隐藏在对象内部,外界无法直接操作和修改。对一个类或对象实现良好的封装,可以实现以下目的:隐藏类的实现细节;让使用者只能通过事先预定的方法来访问数据,从而可以在该方法里加入控制逻辑,限制对成员变量的不合理访问;可进行数据检查,从而有利于保证对象信息的完整性;便于修改,提高代码的可维护性。
14.对多态的理解。
因为子类其实是一种特殊的父类,因此Java允许把一个子类对象直接赋值给一个父类引用变量,无需任何类型转换,或者被成为向上转型,向上转型由系统自动完成。
当把一个子类对象直接赋值给父类引用变量时,例如BaseClass obj = new SubClass();这个obj引用变量的编译类型时BaseClass,而运行时类型时SubClass,当运行时调用该引用变量时,其方法行为总是表现出子类方法的行为特征,而不是父类方法的行为特征,这就可能出现相同类型的变量,调用同一方法时呈现出多种不同的行为特征,这就是多态。
15.Java中的多态是如何实现的。
多态的实现离不开继承,在设计程序时,我们可以将参数的类型定义为父类型。在调用程序时则可以根据实际情况传入该父类类型的某个子类型的实例,这样就实现了多态,对于父类型,可以有三种形式即普通的类、抽象类、接口。对于子类型,则需要根据它自身的特征,重写父类的某些方法,或实现抽象类/接口的某些抽象方法。
16Java为什么时单继承,为什么不能多继承。
首先,Java是单继承的,指的是Java中的一个类只能有一个直接父类。Java不能多继承则是说Java中一个类不能直接继承多个父类;
其次,Java在设计时借鉴了C++的语法,而C++是支持多继承的。Java语言之所以摒弃了多继承这项特征是因为多继承容易产生混淆。比如,两个父类中包含相同的方法时,子类在调用该方法或重写该方法时就会很迷惑;
准确来说,Java是可以实现“多继承”的。因为尽管一个类只能有一个直接父类,但是却可以有任意多个间接父类。这样的设计方式避免了多继承时所产生的混淆。
17.重写和重载的区别:
重载发生在同一个类中,若多个方法之间方法名相同。参数列表不同,则它们构成重载关系。重载与方法的返回值以及访问修饰符无关,即重载的方法不能根据返回类型进行区分。
重写发生在父类子类中,若子类方法想要和父类方法构成重写关系,则它们的方法名、参数列表必须与父类方法相同,另外,返回值要小于等于父类方法,抛出的异常要小于等于父类方法,访问修饰符则要大于等于父类方法,如果父类方法访问的修饰符是private,则子类不能对其重写。
18.构造方法能不能重写?
构造方法不能重写。因为构造方法需要和类保持同名,而重写的要求时子类方法要父类方法保持同名。如果允许重写构造方法的话,那么子类中将会存在与类名不同的构造方法,这就与构造方法的要求是矛盾的。
19.Object类中的方法
Class<?> getClass():返回该对象的运行时类;
boolean equals(Object obj):判断指定对象与该对象是否相等;
int hashCode():返回该对象的hashCode值。在默认情况下,Object类的hashCode()方法,不再根据地址来计算其hashCode()方法值;
String toString():返回该对象的字符串表示,当程序使用System.out.println()方法输出一个对象或者把某个对象和字符串进行连接运算时,系统会自动调用该对象的toString()方法返回该对象的字符串表示。Object类的toString()方法返回 运行时类名@十六进制hashCode值格式的字符串,但很多类都重写了toString()方法,用于返回可以描述该对象信息的字符串。
另外,Object类还提供了wait()、notify()、notifyAll()这几种方法,通过这几个方法可以控制线程的暂停和运行。Object类还提供了一个clone()方法,该方法用于帮助其他对象来实现“自我克隆”,所谓的自我克隆就是得到一个当前对象的副本,而且两者之间完全隔离。由于该方法使用了protected修饰,因此他只能被子类重写或者调用。