JAVA 基础、语法:
1. java 跨平台原理(字节码文件、 虚拟机 )
C/C++语言都直接编译成针对特定平台机器码。如果要跨平台,需要使用相应的编译器重新编译。
Java源程序(.java)要先编译成与平台无关的字节码文件(.class),然后字节码文件再解释成机器码运行。解释是通过Java虚拟机来执行的。
字节码文件不面向任何具体平台,只面向虚拟机。
JAVA虚拟机 是可运行Java字节码文件的虚拟计算机。不同平台的虚拟机是不同的,但它们都提供了相同的接口。
Java语言具有一次编译,到处运行的特点。就是说编译后的.class可以跨平台运行,前提是该平台具有相应的Java虚拟机。但是性能比C/C++要低。
Java的跨平台原理决定了其性能没有C/C++高
2.Java的安全性
语言层次的安全性主要体现在:
Java取消了强大但又危险的指针,而代之以引用。由于指针可进行移动运算,指针可随便指向一个内存区域,而不管这个区域是否可用,这样做是危险的,因为原来这个内存地址可能存储着重要数据或者是其他程序运行所占用的,并且使用指针也容易数组越界。
垃圾回收机制:不需要程序员直接控制内存回收,由垃圾回收器在后台自动回收不再使用的内存。避免程序忘记及时回收,导致内存泄露。避免程序错误回收程序核心类库的内存,导致系统崩溃。
异常处理机制:Java异常机制主要依赖于try、catch、finally、throw、 throws 五个关键字。
强制类型转换 :只有在满足强制转换规则的情况下才能强转成功。
底层的安全性可以从以下方面来说明
Java在字节码的传输过程中使用了公开密钥加密机制(PKC)。
在运行环境提供了四级安全性保障机制:
字节码校验器 -类装载器 -运行时内存布局 -文件访问限制
3.Java三大版本
Java2平台包括标准版(J2SE)、企业版(J2EE)和微缩版( J2ME )三个版本:
Standard Edition(标准版) J2SE 包含那些构成 Java 语言核心的类。
比如:数据库连接、接口定义、输入/输出、网络编程
Enterprise Edition(企业版) J2EE 包含J2SE 中的类,并且还包含用于开发企业级应用的类。
比如 servlet 、 JSP 、XML、事务控制
Micro Edition(微缩版) J2ME 包含J2SE中一部分类,用于 消费类电子产品 的软件开发。
比如:呼机、智能卡、手机、PDA、机顶盒
他们的范围是:J2SE包含于J2EE中,J2ME包含了J2SE的核心类,但新添加了一些专有类
应用场合,API的覆盖范围各不相同。
4.什么是 JVM ?什么是 jdk ? 什么是 JRE ?
JVM : JVM是Java Virtual Machine(Java虚拟机)的缩写,它是整个java实现跨平台的最核心的部分,所有的java程序会首先被编译为.class的类文件,这种类文件可以在虚拟机上执行,也就是说class并不直接与机器的操作系统相对应,而是经过虚拟机间接与操作系统交互,由虚拟机将程序解释给本地系统执行。JVM是Java平台的基础,和实际的机器一样,它也有自己的 指令集 ,并且在运行时操作不同的内存区域。 JVM通过抽象操作系统和 CPU 结构,提供了一种与平台无关的代码执行方法,即与特殊的实现方法、主机硬件、主机操作系统无关。JVM的主要工作是解释自己的指令集(即字节码)到CPU的指令集或对应的系统调用,保护用户免被恶意程序骚扰。 JVM对上层的Java源文件是不关心的,它关注的只是由源文件生成的类文件(. class文件 )。
JRE: JRE是java runtime environment(java运行环境)的缩写。光有JVM还不能让class文件执行,因为在解释class的时候JVM需要调用解释所需要的类库lib。在JDK的安装目录里你可以找到jre目录,里面有两个文件夹bin和lib,在这里可以认为 bin 里的就是jvm,lib中则是jvm工作所需要的类库,而jvm和lib和起来就称为jre。所以,在你写完java程序编译成.class之后,你可以把这个.class文件和jre一起打包发给朋友,这样你的朋友就可以运行你写程序了(jre里有运行.class的java.exe)。JRE是Sun公司发布的一个更大的系统,它里面就有一个JVM。JRE就与具体的CPU结构和操作系统有关,是运行Java程序必不可少的(除非用其他一些编译环境编译成.exe 可执行文件 ……),JRE的地位就象一台PC机一样,我们写好的 Win32 应用程序需要操作系统帮我们运行,同样的,我们编写的Java程序也必须要JRE才能运行。
JDK: JDK是java development kit(java开发工具包)的缩写。每个学java的人都会先在机器上装一个JDK,那 让我们看一下JDK的安装目录。在目录下面有六个文件夹、一个src类库源码压缩包、和其他几个声明文件。其中,真正在运行java时起作用的是以下四个文件夹:bin、 include 、lib、jre。现在我们可以看出这样一个关系,JDK包含JRE,而JRE包含JVM。
bin:最主要的是编译器( javac .exe)
include:java和JVM交互用的头文件
lib:类库
jre:java运行环境
(注意:这里的bin、lib文件夹和jre里的bin、lib是不同的)总的来说JDK是用于java程序的开发,而jre则是只能运行class而没有编译的功能。 eclipse 、 idea 等其他IDE有自己的编译器而不是用JDK bin目录中自带的,所以在安装时你会发现他们只要求你选jre路径就ok了。
JDK,JRE,JVM三者关系概括如下:
jdk是JAVA程序开发时用的开发工具包,其内部也有JRE运行环境JRE。JRE是JAVA程序运行时需要的运行环境,就是说如果你光是运行JAVA程序而不是去搞开发的话,只安装JRE就能运行已经存在的JAVA程序了。JDk、JRE内部都包含JAVA虚拟机JVM,JAVA虚拟机内部包含许多应用程序的类的解释器和类加载器等等。
5.Java三种注释类型
共有单行注释、多行注释、文档注释3种注释类型。使用如下:
单行注释,采用“//”方式.只能注释一行代码。如://类成员变量
多行注释,采用“/*…*/”方式,可注释多行代码,其中不允许出现嵌套。如:
/*System.out.println(“a”);
System.out.println(“b”);
System.out.println(“c”);*/
文档注释,采用“/**…*/”方式。如:
/**
* 子类 Dog
* @author Administrator
**/
public class Dog extends Animal{}
6.8种基本数据类型及其字节数
数据类型 | 关键字 | 字节数 | ||
数值型 | 整数型 | byte | 1 | |
short | 2 | |||
int | 4 | |||
long | 8 | |||
浮点型 | float | 4 | ||
double | 8 | |||
布尔 型 | boolean | 1(位) | ||
字符型 | char | 2 |
7.i++和++i的异同之处
共同点:
1、i++和++i都是变量自增1,都等价于i=i+1
2、如果i++,++i是一条单独的语句,两者没有任何区别
3、i++和++i的使用仅仅针对变量。 5++和++5会报错,因为5不是变量。
不同点:
如果i++,++i不是一条单独的语句,他们就有区别i++ :先运算后增1。如:
int x=;
int y=x++;
System.out.println("x="+x+", y="+y);
//以上代码运行后输出结果为:x=, y=5
++i : 先增1后运算。如:
int x=;
int y=++x;
System.out.println("x="+x+", y="+y);
//以上代码运行后输出结果为:x=, y=6
8.&和&&的区别和联系,|和||的区别和联系
&和&&的联系(共同点):
&和&&都可以用作逻辑与运算符,但是要看使用时的具体条件来决定。
操作数1&操作数2,操作数1&&操作数2,
表达式1&表达式2,表达式1&&表达式2,
情况1:当上述的操作数是boolean类型变量时,&和&&都可以用作逻辑与运算符。
情况2:当上述的表达式结果是boolean类型变量时,&和&&都可以用作逻辑与运算符。
表示逻辑与(and),当 运算符 两边的表达式的结果或操作数都为true时,整个运算结果才为true,否则,只要有一方为false,结果都为false。
&和&&的区别(不同点):
(1)、&逻辑运算符称为逻辑与运算符,&&逻辑运算符称为短路与运算符,也可叫逻辑与运算符。
对于&:无论任何情况,&两边的操作数或表达式都会参与计算。
对于&&:当&&左边的操作数为false或左边表达式结果为false时,&&右边的操作数或表达式将不参与计算,此时最终结果都为false。
综上所述,如果逻辑与运算的第一个操作数是false或第一个表达式的结果为false时,对于第二个操作数或表达式是否进行运算,对最终的结果没有影响,结果肯定是false。推介平时多使用&&,因为它效率更高些。
、&还可以用作 位运算符 。当&两边操作数或两边表达式的结果不是boolean类型时,&用于按位与运算符的操作。
|和||的区别和联系与&和&&的区别和联系类似
9.用最有效率的方法算出2乘以8等于多少
使用 位运算 来实现效率最高。位运算符是对操作数以 二进制 比特位为单位进行操作和运算,操作数和结果都是整型数。对于位运算符“<<”, 是将一个数左移n位,就相当于乘以了2的n次方,那么,一个数乘以8只要将其左移3位即可,位运算cpu直接支持的,效率最高。所以,2乘以8等于几的最效率的方法是2 << 3
10.基本数据类型的类型转换规则
基本类型转换分为自动转换和强制转换。
自动转换规则:容量小的数据类型可以自动转换成容量大的数据类型,也可
以说低级自动向高级转换。这儿的容量指的不是字节数,而是指类型表述的范围。
强制转换规则:高级变为低级需要强制转换。
如何转换:
(1)赋值运算符“=”右边的转换,先自动转换成表达式中级别最高的数据类型,再进行运算。
(2)赋值运算符“=”两侧的转换,若左边级别>右边级别,会自动转换;若左边级别 == 右边级别,不用转换;若左边级别 < 右边级别,需强制转换。
(3)可以将整型常量直接赋值给byte, short, char等类型变量,而不需要进行强制类型转换,前提是不超出其表述范围,否则必须进行强制转换。
11. if 多分支语句和switch多分支语句的异同之处
相同之处:都是分支语句,多超过一种的情况进行判断处理。
不同之处:
switch更适合用于多分支情况,就是有很多种情况需要判断处理,判断条件类型单一,只有一个入口,在分支执行完后(如果没有break跳出),不加判断地执行下去;而if—elseif—else多分枝主要适用于分支较少的分支结构,判断类型不是单一,只要一个分支被执行后,后边的分支不再执行。switch为等值判断(不允许比如>= <=),而if为等值和区间都可以,if的使用范围大。
12. while 和do-while循环的区别
while先判断后执行,第一次判断为false,循环体一次都不执行
do while 先执行 后判断,最少执行1次。
如果while循环第一次判断为true, 则两种循环没有区别。
13.break和continue的作用
break : 结束当前循环并退出当前循环体。
break还可以退出switch语句
continue: 循环体中后续的语句不执行,但是循环没有结束,继续进行循环条件的判断(for循环还会i++)。continue只是结束本次循环。
14.请使用 递归算法 计算n!
package com.bjsxt;
import java.io. File ;
public class $ {
public static void main(String[] args) {
String path = "D:/301SXT";
test(path);
}
private static void test(String path) {
File f = new File(path);
File[] fs = f.listFiles();
if (fs == null) {
return;
}
for (File file : fs) {
if (file.isFile()) {
System.out.println(file.getPath());
} else {
test(file.getPath());
}
}
}
15.递归的定义和优缺点
递归算法是一种直接或者间接地调用自身算法的过程。在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使 算法 的描述简洁而且易于理解。
递归算法解决问题的特点:
(1) 递归就是在过程或函数里调用自身。
(2) 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
(3) 递归算法解题通常显得很简洁,但运行效率较低。所以一般不提倡用递归算法设计程序。
(4) 在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。所以一般不提倡用递归算法设计程序。
16.数组的特征
数组是(相同类型数据)的(有序)(集合)
数组会在内存中开辟一块连续的空间,每个空间相当于之前的一个变量,称为数组的元素element
元素的表示 数组名[下标或者索引] scores[7] scores[0] scores[9]
索引 从0开始
每个数组元素有默认值 double 0.0 boolean false int 0
数组元素有序的,不是大小顺序,是索引 的顺序
数组中可以存储基本数据类型,可以存储引用数据类型;但是对于一个数组而言,数组的类型是固定的,只能是一个
length:数组的长度
数组的长度是固定的,一经定义,不能再发生变化(数组的扩容)
17.请写出 冒泡排序 代码
package com.bjsxt;
public class TestBubbleSort {
public static void sort(int[] a) {
int temp =;
// 外层循环,它决定一共走几趟
for (int i =; i <a.length-1; ++i) {
//内层循环,它决定每趟走一次
for (int j =; j <a.length-i-1 ; ++j) {
//如果后一个大于前一个
if (a[j +] < a[j]) {
//换位
temp = a[j];a[j] = a[j +];a[j + 1] = temp;
}
}
}
public static void sort(int[] a) {
int temp =;
for (int i =; i <a.length-1; ++i) {
//通过符号位可以减少无谓的比较,如果已经有序了,就退出循环
int flag =;
for (int j =; j <a.length-1-i ; ++j) {
if (a[j +] < a[j]) {
temp = a[j];
a[j] = a[j +];
a[j +] = temp;
flag =;
}
}
if(flag ==){
break;
}
}
}
}
18.请写出 选择排序 的代码
package com.bjsxt;
public class TestSelectSort {
public static void sort(int arr[]) {
int temp =;
for (int i =; i < arr.length - 1; i++) {
// 认为目前的数就是最小的, 记录最小数的下标
int minIndex = i;
for (int j = i +; j < arr.length; j++) {
if (arr[minIndex] > arr[j]) {
// 修改最小值的下标
minIndex = j;
}
}
// 当退出for就找到这次的最小值
if (i != minIndex) {
temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
}
}
19.请写出插入排序的代码
package com.bjsxt;
public class TestInsertSort {
public static void sort(int arr[]) {
int i, j;
for (i =; i < arr.length; i++) {
int temp = arr[i];
for (j = i; j > && temp < arr[j - 1]; j--) {
arr[j] = arr[j -];
}
arr[j] = temp;
}
}
}
20.可变参数的作用和特点
总结1:可变参数
1.可变参数的形式 …
2.可变参数只能是方法的形参
3.可变参数对应的实参可以0,1,2…..个,也可以是一个数组
4.在可变参数的方法中,将可变参数当做数组来处理
5.可变参数最多有一个,只能是最后一个
6.可变参数好处:方便 简单 减少重载方法的数量
7.如果定义了可变参数的方法,不允许同时定义相同类型数组参数的方法
总结2:数组做形参和可变参数做形参联系和区别
联系:
1.实参都可以是数组;2.方法体中,可变参数当做数组来处理
区别:
1.个数不同 可变参数只能有一个数组参数可以多个
2.位置不同 可变参数只能是最后一个 数组参数位置任意
3.实参不同 可变参数实参可以0,1,2…..个,也可以是一个数组,数组的实参只能是数组
21.类和对象的关系
类是对象的抽象,而对象是类的具体实例。类是抽象的,不占用内存,而对象是具体的,占用存储空间。类是用于创建对象的蓝图,它是一个定义包括在特定类型的对象中的方法和变量的软件模板。
类和对象好比图纸和实物的关系,模具和铸件的关系。
比如人类就是一个概念,人类具有身高,体重等属性。人类可以做吃饭、说话等方法。
小明就是一个具体的人,也就是实例,他的属性是具体的身高200cm,体重180kg,他做的方法是具体的吃了一碗白米饭,说了“ 12345 ”这样一句话。
22.面向过程和面向对象的区别
两者都是软件开发思想,先有面向过程,后有面向对象。在大型项目中,针对面向过程的不足推出了面向对象开发思想。
比喻
蒋介石 和毛泽东分别是面向过程和面向对象的杰出代表,这样充分说明,在解决复制问题时,面向对象有更大的优越性。
面向过程是蛋炒饭,面向对象是盖浇饭。盖浇饭的好处就是“菜”“饭”分离,从而提高了制作盖浇饭的灵活性。饭不满意就换饭,菜不满意换菜。用 软件工程 的专业术语就是“可维护性”比较好,“饭” 和“菜”的 耦合度 比较低。
区别
编程思路不同: 面向过程以实现功能的函数开发为主,而面向对象要首先抽象出类、属性及其方法,然后通过实例化类、执行方法来完成功能。
封装性:都具有封装性,但是面向过程是封装的是功能,而面向对象封装的是数据和功能。
面向对象具有继承性和多态性,而面向过程没有继承性和多态性,所以面向对象优势是明显。
方法重载 和方法重写(覆盖)的区别
|
英文 | 位置不同 | 作用不同 |
重载 | overload | 同一个类中 | 在一个类里面为一种行为提供多种实现方式并提高可读性 |
重写 | override | 子类和父类间 | 父类方法无法满足子类的要求,子类通过方法重写满足要求 |
| 修饰符 | 返回值 | 方法名 | 参数 | 抛出异常 |
重载 | 无关 | 无关 | 相同 | 不同 | 无关 |
重写 | 大于等于 | 小于等于 | 相同 | 相同 | 小于等于 |
23.this和super关键字的作用
this是对象内部指代自身的引用,同时也是解决成员变量和局部变量同名问题;this可以调用成员变量,不能调用局部变量;this也可以调用成员方法,但是在普通方法中可以省略this,在 构造方法 中不允许省略,必须是构造方法的第一条语句。,而且在 静态方法 当中不允许出现this关键字。
super代表对当前对象的直接父类对象的引用,super可以调用直接父类的成员变量(注意权限修饰符的影响,比如不能访问private成员)
super可以调用直接父类的成员方法(注意权限修饰符的影响,比如不能访问private成员);super可以调用直接父类的构造方法,只限构造方法中使用,且必须是第一条语句。
24.static关键字的作用
static可以修饰变量、方法、代码块和内部类
static属性属于这个类所有,即由该类创建的所有对象共享同一个static属性。可以对象创建后通过对象名.属性名和类名.属性名两种方式来访问。也可以在没有创建任何对象之前通过类名.属性名的方式来访问。
static变量和非static变量的区别(都是成员变量,不是局部变量)
1.在内存中份数不同
不管有多少个对象,static变量只有1份。对于每个对象,实例变量都会有单独的一份
static变量是属于整个类的,也称为 类变量 。而非静态变量是属于对象的,也称为实例变量
2.在内存中存放的位置不同
2.在内存中存放的位置不同
3.访问的方式不同
实例变量: 对象名.变量名 stu1.name=”小明明”;
静态变量:对象名.变量名 stu1.schoolName=”西二旗小学”; 不推荐如此使用
类名.变量名 Student.schoolName=”东三旗小学”; 推荐使用
4.在内存中分配空间的时间不同
Student.schoolName=”东三旗小学”;或者Student stu1 = new Student(“小明”,”男”,20,98);
static方法也可以通过对象名.方法名和类名.方法名两种方式来访问
static代码块。当类被第一次使用时(可能是调用static属性和方法,或者创建其对象)执行静态代码块,且只被执行一次,主要作用是实现static属性的初始化。
static内部类:属于整个外部类,而不是属于外部类的每个对象。不能访问外部类的非静态成员(变量或者方法),.可以访问外部类的静态成员
25.final和 abstract 关键字的作用
final和abstract是功能相反的两个关键字,可以对比记忆
abstract 可以用来修饰类和方法,不能用来修饰属性和构造方法;使用abstract修饰的类是抽象类,需要被继承,使用abstract修饰的方法是抽象方法,需要子类被重写。
final 可以用来修饰类、方法和属性,不能修饰构造方法。使用final修饰的类不能被继承,使用final修饰的方法不能被重写,使用final修饰的变量的值不能被修改,所以就成了常量。
特别注意: final修饰基本类型变量,其值不能改变,由原来的变量变为常量;但是final修饰引用类型变量,栈内存中的引用不能改变,但是所指向的堆内存中的对象的属性值仍旧可以改变。例如
package com.bjsxt;
class Test {
public static void main(String[] args) {
final Dog dog = new Dog("欧欧");
dog.name = "美美";//正确
dog = new Dog("亚亚");//错误
}
}
26.final、finally、finalize的区别
final 修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承例如:String类、Math类等。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为final的方法也同样只能使用,不能重写,但是能够重载。 使用final修饰的对象,对象的引用地址不能变,但是对象的值可以变!
finally 在异常处理时提供 finally 块来执行任何清除操作。如果有finally的话,则不管是否发生异常,finally语句都会被执行。一般情况下,都把关闭物理连接(IO流、数据库连接、Socket连接)等相关操作,放入到此代码块中。
finalize 方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要清理工作。finalize() 方法是在垃圾收集器删除对象之前被调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。 一般情况下,此方法由JVM调用,程序员不要去调用!
27.写出java.lang.Object类的六个常用方法
(1)public boolean equals(java.lang.Object)
比较对象的地址值是否相等,如果子类重写,则比较对象的内容是否相等;
(2)public native int hashCode() 获取哈希码
(3)public java.lang.String toString() 把数据转变成字符串
(4)public final native java.lang.Class getClass() 获取类结构信息
(5)protected void finalize() throws java.lang.Throwable
垃圾回收前执行的方法
(6)protected native Object clone() throws
java.lang.CloneNotSupportedException 克隆
(7)public final void wait() throws java.lang.InterruptedException
多线程中等待功能
(8)public final native void notify() 多线程中唤醒功能
(9)public final native void notifyAll() 多线程中唤醒所有等待线程的功能
28.private/默认/protected/public权限修饰符的区别
|
同一个类 | 同一个包 | 子类 | 所有类 |
private | * | |||
defailt | * | * | ||
protected | * | * | * | |
public | * | * | * | * |
类的访问权限只有两种
public 公共的 可被同一项目中所有的类访问。 (必须与文件名同名)
default 默认的 可被同一个包中的类访问。
成员(成员变量或成员方法)访问权限共有四种:
public 公共的 可以被项目中所有的类访问。(项目可见性)
protected 受保护的 可以被这个类本身访问;同一个包中的所有其他的类访问;被它的子类(同一个包以及不同包中的子类)访问。(子类可见性)
default 默认的被这个类本身访问;被同一个包中的类访问。(包可见性)
private 私有的 只能被这个类本身访问。(类可见性)
29.继承条件下构造方法的执行过程
继承条件下构造方法的调用规则如下:
情况1: 如果子类的构造方法中没有通过super显式调用父类的有参构造方法,也没有通过this显式调用自身的其他构造方法,则系统会默认先调用父类的无参构造方法。在这种情况下,写不写“super();”语句,效果是一样的。
情况2: 如果子类的构造方法中通过super显式调用父类的有参构造方法,那将执行父类相应构造方法,而不执行父类无参构造方法。
情况3: 如果子类的构造方法中通过this显式调用自身的其他构造方法,在相应构造方法中应用以上两条规则。
特别注意的是, 如果存在多级继承关系,在创建一个子类对象时,以上规则会多次向更高一级父类应用,一直到执行顶级父类Object类的无参构造方法为止。
30.==和equals的区别和联系
“==”是关系运算符,equals()是方法,同时他们的结果都返回布尔值;
“==”使用情况如下:
a) 基本类型,比较的是值
b) 引用类型,比较的是地址
c) 不能比较没有父子关系的两个对象
equals()方法使用如下:
a) 系统类一般已经覆盖了equals(),比较的是内容。
b) 用户自定义类如果没有覆盖equals(),将调用父类的equals (比如是Object),而Object的equals的比较是地址(return (this == obj);)
c) 用户自定义类需要覆盖父类的equals()
注意:Object的==和equals比较的都是地址,作用相同
31.谈谈Java的多态
实现多态的三个条件(前提条件,向上转型、向下转型)
1、继承的存在;(继承是多态的基础,没有继承就没有多态)
2、子类重写父类的方法。(多态下会调用子类重写后的方法)
3、父类引用变量指向子类对象。(涉及子类到父类的类型转换)
向上转型 Student person = new Student()
将一个父类的引用指向一个子类对象,成为向上转型,自动进行类型转换。此时通过父类引用变量调用的方法是子类覆盖或继承父类的方法,而不是父类的方法此时通过父类引用变量无法调用子类特有的方法。
向下转型 Student stu = (Student)person;
将一个指向子类对象的引用赋给一个子类的引用,成为向下转型,此时必须进行强制类型转换。向下转型必须转换为父类引用指向的真实子类类型,,否则将出现ClassCastException,不是任意的强制转换
向下转型时可以结合使用instanceof运算符进行强制类型转换,比如出现转换异常—ClassCastException
32.简述Java的垃圾回收机制
传统的C/C++语言,需要程序员负责回收已经分配内存。
显式回收垃圾回收的缺点:
1)程序忘记及时回收,从而导致内存泄露,降低系统性能。
2)程序错误回收程序核心类库的内存,导致系统崩溃。
Java语言不需要程序员直接控制内存回收,是由JRE在后台自动回收不再使用的内存,称为垃圾回收机制,简称GC;
1)可以提高编程效率。
2)保护程序的完整性。
3)其开销影响性能。Java虚拟机必须跟踪程序中有用的对象,确定哪些是无用的。
垃圾回收机制的 特点
1)垃圾回收机制回收JVM堆内存里的对象空间,不负责回收栈内存数据。
2)对其他物理连接,比如数据库连接、输入流输出流、Socket连接无能为力。
3)垃圾回收发生具有不可预知性,程序无法精确控制垃圾回收机制执行。
4)可以将对象的引用变量设置为null,暗示垃圾回收机制可以回收该对象。
现在的JVM有多种垃圾回收 实现算法,表现各异。
垃圾回收机制回收任何对象之前,总会先调用它的finalize方法(如果覆盖该方法,让一个新的引用变量重新引用该对象,则会重新激活对象)。
程序员可以通过System.gc()或者Runtime.getRuntime().gc()来通知系统进行垃圾回收,会有一些效果,但是系统是否进行垃圾回收依然不确定。
永远不要主动调用某个对象的finalize方法,应该交给垃圾回收机制调用。
33.基本数据类型和包装类
1) 八个基本数据类型的包装类
基本数据类型 | 包装类 |
byte | Byte |
boolean | Boolean |
short | Short |
char | Character |
int | Integer |
long | Long |
float | Float |
double | Double |
2)为什么为基本类型引入包装类
2.1基本数据类型有方便之处,简单、高效。
2.2但是Java中的基本数据类型却是不面向对象的(没有属性、方法),这在实际使用时存在很多的不便(比如集合的元素只能是Object)。
为了解决这个不足,在设计类时为每个基本数据类型设计了一个对应的类进行包装,这样八个和基本数据类型对应的类统称为包装类(Wrapper Class)。
3) 包装类和基本数据类型之间的转换
3.1包装类—— wrapperInstance.xxxValue() ——>基本数据类型
3.2包装类——-new WrapperClass(primitive)
3.2包装类——-new WrapperClass(primitive)
4) 自动装箱和自动拆箱
JDK1.5提供了自动装箱(autoboxing)和自动拆箱(autounboxing)功能, 从而实现了包装类和基本数据类型之间的自动转换
5) 包装类还可以实现基本类型变量和字符串之间的转换
基本类型变量—>String.valueof()—>字符串 基本类型变量<—WrapperClass.parseXxx(string)—字符串
34.Integer与int的区别
int是java提供的8种原始数据类型之一,Java为每个原始类型提供了封装类,Integer是java为int提供的封装类。
int是java提供的8种原始数据类型之一,Java为每个原始类型提供了封装类,Integer是java为int提供的封装类。
在Hibernate中,如果将OID定义为Integer类型,那么Hibernate就可以根据其值是否为null而判断一个对象是否是临时的,如果将OID定义为了int类型,还需要在hbm映射文件中设置其unsaved-value属性为0。
另外,Integer提供了多个与整数相关的操作方法,例如,将一个字符串转换成整数,Integer中还定义了表示整数的最大值和最小值的常量。
35.java.sql.Date和java.util.Date的联系和区别
1) java.sql.Date是java.util.Date的子类,是一个包装了毫秒值的瘦包装器,允许 JDBC 将毫秒值标识为 SQL DATE 值。毫秒值表示自 1970 年 1 月 1 日 00:00:00 GMT 以来经过的毫秒数。 为了与 SQL DATE 的定义一致,由 java.sql.Date 实例包装的毫秒值必须通过将时间、分钟、秒和毫秒设置为与该实例相关的特定时区中的零来“规范化”。 说白了,java.sql.Date就是与数据库Date相对应的一个类型,而java.util.Date是纯java的Date。
2)JAVA里提供的日期和时间类,java.sql.Date和java.sql.Time,只会从数据库里读取某部分值,这有时会导致丢失数据。例如一个包含2002/05/22 5:00:57 PM的字段,读取日期时得到的是2002/05/22,而读取时间时得到的是5:00:57 PM. 你需要了解数据库里存储时间的精度。有些数据库,比如MySQL,精度为毫秒,然而另一些数据库,包括Oracle,存储SQL DATE类型数据时,毫秒部分的数据是不保存的。以下操作中容易出现不易被发现的BUG:获得一个JAVA里的日期对象。 从数据库里读取日期 试图比较两个日期对象是否相等。如果毫秒部分丢失,本来认为相等的两个日期对象用Equals方法可能返回false。.sql.Timestamp类比java.util.Date类精确度要高。这个类包了一个getTime()方法,但是它不会返回额外精度部分的数据,因此必须使用…
总之,java.util.Date 就是Java的日期对象,而java.sql.Date 是针对SQL语句使用的,只包含日期而没有时间部分。
36.使用递归算法输出某个目录下所有文件和子目录列表
package com.bjsxt;
import java.io.File;
public class $ {
public static void main(String[] args) {
String path = "D:/SXT";
test(path);
}
private static void test(String path) {
File f = new File(path);
File[] fs = f.listFiles();
if (fs == null) {
return;
}
for (File file : fs) {
if (file.isFile()) {
System.out.println(file.getPath());
} else {
test(file.getPath());
}
}
}
37.关于Java编译,下面哪一个正确()(选择一项)
A | Java程序经编译后产生machine code | |
B. | Java程序经编译后会生产byte code | |
C. | Java程序经编译后会产生DLL | |
D. | 以上都不正确 | |
答案:B 分析: Java是解释型语言,编译出来的是字节码; 因此A不正确,C是C/C++语言编译动态链接库的文件为.DLL; 正确答案为B |
38.下列说法正确的有()(选择一项)
A | class中的construtor不可省略 | |
B. | construtor与class同名,但方法不能与class同名 | |
C. | construtor在一个对象被new时执行 | |
D. | 一个class只能定义一个construtor | |
答案:C 分析:A:如果class中的construtor省略不写,系统会默认提供一个无参构造 B:方法名可以与类名同名,只是不符合命名规范 D:一个class中可以定义N多个construtor,这些construtor构成构造方法的重载 |
39.Java中接口的修饰符可以为()(选择一项)
A | private | |
B. | protected | |
C. | final | |
D. | abstract | |
答案:D 分析:接口中的访问权限修饰符只可以是public或default 接口中的所有的方法必须要实现类实现,所以不能使用final 接口中所有的方法默认都是abstract的,所以接口可以使用abstract修饰,但通常abstract可以省略不写 |
40.给定以下代码,程序将输出 ()(选择一项)
class A {
public A(){
System.out.println("A");
}
}
class B extends A{
public B(){
System.out.println("B");
}
public static void main(String[] args) {
B b=new B();
}
}
A | 不能通过编译 | |
B. | 通过编译,输出AB | |
C. | 通过编译,输出B | |
D. | 通过编译,输出A | |
答案:B 分析:在继承关系下,创建子类对象,先执行父类的构造方法,再执行子类的构造方法。 |
41.下列关于关键字的使用说法错误的是()(选择一项)
A | abstract不能与final并列修饰同一个类 | |
B. | abstract类中可以有private的成员 | |
C. | abstract方法必须在abstract类中 | |
D. | static方法能处理非static的属性 | |
答案:D 分析:因为static得方法在装载class得时候首先完成,比 构造方法早,此时非static得属性和方法还没有完成初始化所以不能调用。 |
42.下列哪些语句关于内存回收的说法是正确的()(选择一项)
A | 程序员必须创建一个线程来释放内存 | |
B. | 内存回收程序负责释放无用内存 | |
C. | 内存回收程序允许程序员直接释放内存 | |
D. | 内存回收程序可以在指定的时间释放内存对象 | |
答案:B 分析: A. 程序员不需要创建线程来释放内存. C. 也不允许程序员直接释放内存. D. 不一定在什么时刻执行垃圾回收. |
43.选出合理的标识符()(选择两项)
A | _sysl_111 | |
B. | 2 mail | |
C. | $change | |
D. | class | |
答案:AC 分析: 标识符的命令规范,可以包含字母、数字、下划线、$,不能以数字开头,不能是Java关键字 |
44.下列说法正确的是()(选择多项)
A | java.lang.Cloneable是类 | |
B. | java.langRunnable是接口 | |
C. | Double对象在java.lang包中 | |
D. | Double a=1.0是正确的java语句 | |
Double a=1.0是正确的java语句 分析:java.lang.Cloneable是接口 |
45.定义一个类名为”MyClass.java”的类,并且该类可被一个工程中的所有类访问,那么该类的正确声明为()(选择两项)
A | 45.定义一个类名为”MyClass.java”的类,并且该类可被一个工程中的所有类访问,那么该类的正确声明为()(选择两项) | |
B. | class MyClass extends Object | |
C. | public class MyClass | |
D. | public class MyClass extends Object | |
答案:CD 分析: A 类的访问权限只能是public或default B使用默认访问权限的类,只能在本包中访问 |
46.面向对象的特征有哪些方面?请用生活中的例子来描述。
答: 面向对象的三大特征:封装、继承、多态。
举例:(比如设计一个游戏)我现在创建了一个对象,名叫战士。
战士的属性是—性别,年龄,职业,等级,战斗力,血量。
它的方法—战斗,逃跑,吃饭,睡觉,死。
后来,我又建了一个对象,叫人。
属性:性别,年龄,职业,等级,血量
方法:逃跑,吃饭,睡觉,死。
我让人,成为战士的父类,战士可以直接继承人的属性和方法。
战士修改成—
属性:战斗力。
方法:战斗。
看上去战士的资料变少了,实际上没有,我们仍然可以调用方法—战士.死。
而且我们还可以重载战士.死的方法,简称重载死法。
我还建了一个对象—法师,父类也是人。
属性:法力值
方法:施法,泡妞。
你看,用了继承,创建对象变得更方便了。
再后来,我又建立了一个对象,叫怪物。
属性:等级,战力,血量。
方法:战斗,死。
建了个对象,叫白兔怪,父类怪物,可继承怪物所有的属性和方法。
属性:毛色。
方法:卖萌,吃胡萝卜。
47.说明内存泄漏和内存溢出的区别和联系,结合项目经验描述Java程序中如何检测?如何解决?
答:
内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。
内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。
memory leak会最终会导致out of memory!
48.什么是Java的序列化,如何实现Java的序列化?列举在哪些程序中见过Java序列化?
答: Java中的序列化机制能够将一个实例对象(只序列化对象的属性值,而不会去序列化什么所谓的方法。)的状态信息写入到一个字节流中使其可以通过socket进行传输、或者持久化到存储数据库或文件系统中;然后在需要的时候通过字节流中的信息来重构一个相同的对象。一般而言,要使得一个类可以序列化,只需简单实现java.io.Serializable接口即可。
对象的序列化主要有两种用途:
1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
2) 在网络上传送对象的字节序列。
在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存。比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些seesion先序列化到硬盘中,等要用了,再把保存在硬盘中的对象还原到内存中。
当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。
49.不通过构造函数也能创建对象吗?
答:Java创建对象的几种方式(重要):
1、 用new语句创建对象,这是最常见的创建对象的方法。
2、 运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。
3、 调用对象的clone()方法。
4、运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。
(1)和(2)都会明确的显式的调用构造函数 ;(3)是在内存上对已有对象的影印,所以不会调用构造函数 ;(4)是从文件中还原类的对象,也不会调用构造函数。
50.匿名内部类可不可以继承或实现接口。为什么?
答:匿名内部类是没有名字的内部类,不能继承其它类,但一个内部类可以作为一个接口,由另一个内部类实现.
1、由于匿名内部类没有名字,所以它没有构造函数。因为没有构造函数,所以它必须完全借用父类的构造函数来实例化,换言之:匿名内部类完全把创建对象的任务交给了父类去完成。
2、在匿名内部类里创建新的方法没有太大意义,但它可以通过覆盖父类的方法达到神奇效果,如上例所示。这是多态性的体现。
3、因为匿名内部类没有名字,所以无法进行向下的强制类型转换,持有对一个匿名内部类对象引用的变量类型一定是它的直接或间接父类类型。
51.在Java中,为什么基本类型不能做为HashMap的键值,而只能是引用类型,把引用类型做为HashMap的健值,需要注意哪些地方。
(1) 在Java中是使用泛型来约束HashMap中的key和value的类型的,即HashMap< K, V>;而泛型在Java的规定中必须是对象Object类型的,也就是说HashMap< K, V>可以理解为HashMap< Object, Object>,很显然基本数据类型不是Object类型的,因此不能作为键值,只能是引用类型。虽然我们在HashMap中可以这样添加数据:“map.put(1, “Java”);”,但实际上是将其中的key值1进行了自动装箱操作,变为了Integer类型。
(1) 在Java中是使用泛型来约束HashMap中的key和value的类型的,即HashMap< K, V>;而泛型在Java的规定中必须是对象Object类型的,也就是说HashMap< K, V>可以理解为HashMap< Object, Object>,很显然基本数据类型不是Object类型的,因此不能作为键值,只能是引用类型。虽然我们在HashMap中可以这样添加数据:“map.put(1, “Java”);”,但实际上是将其中的key值1进行了自动装箱操作,变为了Integer类型。
52.简述Java中如何实现多态
实现多态有三个前提条件:
1、 继承的存在;(继承是多态的基础,没有继承就没有多态)。
2、子类重写父类的方法。(多态下会调用子类重写后的方法)。
3、父类引用变量指向子类对象。(涉及子类到父类的类型转换)。
最后使用父类的引用变量调用子类重写的方法即可实现多态。
53.以下对继承的描述锚误的是 ()
A | Java中的继承允许一个子类继承多个父类 | |
B. | 父类更具有通用性,子类更具体 | |
C. | Java中的继承存在着传递性 | |
D. | 当实例化子类时会递归调用父类中的构造方法 | |
答案:A 分析:Java是单继承的,一个类只能继承一个父类。 |
54.Java 中 Math.random()/Math.random()值为?
54.Java 中 Math.random()/Math.random()值为?
如果除数与被除数均为0.0的话,则运行结果为NaN(Not a Number的简写),计算错误。
55.Java中,如果Manager是Employee的子类,那么Pair是Pair的子类吗?
不是,两者没有任何关联;
Pair是单独的类,只不过用不同类型的参数(泛型)进行了相应的实例化而已;所以,Pair< Manager>和Pair< Employee>不是子类的关系。
56.接口和抽象类的区别
56.接口和抽象类的区别
抽象类和接口均包含抽象方法,类必须实现所有的抽象方法,否则是抽象类
抽象类和接口都不能实例化,他们位于继承树的顶端,用来被其他类继承和实现
两者的区别主要体现在两方面:语法方面和设计理念方面
语法方面的区别是比较低层次的,非本质的,主要表现在:
接口中只能定义全局静态常量,不能定义变量。抽象类中可以定义常量和变量。
接口中所有的方法都是全局抽象方法。抽象类中可以有0个、1个或多个,甚至全部都是抽象方法。
抽象类中可以有构造方法,但不能用来实例化,而在子类实例化是执行,完成属于抽象类的初始化操作。接口中不能定义构造方法。
一个类只能有一个直接父类(可以是抽象类),但可以充实实现多个接口。一个类使用extends来继承抽象类,使用implements来实现接口。
一个类只能有一个直接父类(可以是抽象类),但可以充实实现多个接口。一个类使用extends来继承抽象类,使用implements来实现接口。
抽象类体现了一种继承关系,目的是复用代码,抽象类中定义了各个子类的相同代码,可以认为父类是一个实现了部分功能的“中间产品”,而子类是“最终产品”。父类和子类之间必须存在“is-a”的关系,即父类和子类在概念本质上应该是相同的。
接口并不要求实现类和接口在概念本质上一致的,仅仅是实现了接口定义的约定或者能力而已。接口定义了“做什么”,而实现类负责完成“怎么做”,体现了功能(规范)和实现分离的原则。接口和实现之间可以认为是一种“has-a的关系”
57.同步代码块和同步方法有什么区别
相同点:
同步方法就是在方法前加关键字synchronized,然后被同步的方法一次只能有一个线程进入,其他线程等待。而同步代码块则是在方法内部使用大括号使得一个代码块得到同步。同步代码块会有一个同步的“目标”,使得同步块更加灵活一些(同步代码块可以通过“目标”决定需要锁定的对象)。
一般情况下,如果此“目标”为this,同步方法和代码块没有太大的区别。
区别:
同步方法直接在方法上加synchronized实现加锁,同步代码块则在方法内部加锁。很明显,同步方法锁的范围比较大,而同步代码块范围要小点。一般同步的范围越大,性能就越差。所以一般需要加锁进行同步的时候,范围越小越好,这样性能更好。
58.静态内部类和内部类有什么区别
静态内部类不需要有指向外部类的引用。但非静态内部类需要持有对外部类的引用。
静态内部类可以有静态成员(方法,属性),而非静态内部类则不能有静态成员(方法,属性)。
非静态内部类能够访问外部类的静态和非静态成员。静态内部类不能访问外部类的非静态成员,只能访问外部类的静态成员。
实例化方式不同:
1) 静态内部类:不依赖于外部类的实例,直接实例化内部类对象
2) 非静态内部类:通过外部类的对象实例生成内部类对象
59.反射的概念与作用
反射的概念:
反射,一种计算机处理方式。是程序可以访问、检测和修改它本身状态或行为的一种能力。
Java反射可以于运行时加载,探知和使用编译期间完全未知的类.
程序在运行状态中, 可以动态加载一个只有名称的类, 对于任意一个已经加载的类,都能够知道这个类的所有属性和方法; 对于任意一个对象,都能调用他的任意一个方法和属性;
加载完类之后, 在堆内存中会产生一个Class类型的对象(一个类只有一个Class对象), 这个对象包含了完整的类的结构信息,而且这个Class对象就像一面镜子,透过这个镜子看到类的结构,所以被称之为:反射.
java反射使得我们可以在程序运行时动态加载一个类,动态获取类的基本信息和定义的方法,构造函数,域等。
除了检阅类信息外,还可以动态创建类的实例,执行类实例的方法,获取类实例的域值。反射使java这种静态语言有了动态的特性。
反射的作用:
通过反射可以使程序代码访问装载到JVM 中的类的内部信息
1) 获取已装载类的属性信息
2) 获取已装载类的方法
3) 获取已装载类的构造方法信息
反射的优点:
增加程序的灵活性。
如struts中。请求的派发控制。
当请求来到时。struts通过查询配置文件。找到该请求对应的action。已经方法。
然后通过反射实例化action。并调用响应method。
如果不适用反射,那么你就只能写死到代码里了。
所以说,一个灵活,一个不灵活。
很少情况下是非用反射不可的。大多数情况下反射是为了提高程序的灵活性。因此一般框架中使用较多。因为框架要适用更多的情况。对灵活性要求较高。
60.提供Java存取数据库能力的包是()
A | java.sql | |
B. | java.awt | |
C. | java.lang | |
D. | java.swing | |
答案:A 分析: java.awt和javax.swing两个包是图形用户界面编程所需要的包; java.lang包则提供了Java编程中用到的基础类。 |
61.下列运算符合法的是()(多选)
A | && | |
B. | <> | |
C. | if | |
D. | = | |
答案:AD 分析: &&是逻辑运算符中的短路与; <>表示不等于,但是Java中不能这么使用,应该是!=; if不是运算符; =是赋值运算符。 |
62.执行如下程序代码,c的值打印出来是()
public class Test {
public static void main(String[] args) {
int a =;
int c =;
do{
--c;
a = a -;
} while (a >);
System.out.println(c);
}
}
A | 0 | |
B. | 1 | |
C. | -1 | |
D. | 死循环 | |
答案:C 分析: do-while循环的特点是先执行后判断,所以代码先执行–c操作,得到c为-1,之后执行a=a-1的操作,得到a为-1,然后判断a是否大于0,判断条件不成立,退出循环,输出c为-1。 |
63.下列哪一种叙述是正确的()
A | abstract修饰符可修饰字段,方法和类 | |
B. | 抽象方法的body部分必须用一对大括号{}包住 | |
C. | 声明抽象方法,大括号可有可无 | |
D. | 声明抽象方法不可写出大括号 | |
答案:D 分析: abstract只能修饰方法和类,不能修饰字段; 抽象方法不能有方法体,即没有{}; 同B。 |
64.下列语句正确的是()
A | 形式参数可被视为local Variable | |
B. | 形式参数可被视为local Variable | |
C. | 形式参数可被所有的字段修饰符修饰 | |
D. | 形式参数为方法被调用时,真正被传递的参数 | |
答案:A 分析: local Variable为局部变量,形参和局部变量一样都只有在方法内才会发生作用,也只能在方法中使用,不会在方法外可见; 对于形式参数只能用final修饰符,其它任何修饰符都会引起编译器错误; 真正被传递的参数是实参; 形式参数可是基本数据类型也可以是引用类型(对象)。 |
65.下列哪种说法是正确的()
A | 实例方法可直接调用超类的实例方法 | |
B. | 实例方法可直接调用超类的类方法 | |
C. | 实例方法可直接调用其他类的实例方法 | |
D. | 实例方法可直接调用本类的类方法 | |
答案:D 分析: 实例方法不可直接调用超类的私有实例方法; 实例方法不可直接调用超类的私有的类方法; 要看访问权限。 |
66.Java程序的种类有()(多选)
A | 类 (Class) | |
B. | Applet | |
C. | Application | |
D. | Servlet | |
答案:BCD 分析: 是Java中的类,不是程序; 内嵌于Web文件中,由浏览器来观看的Applet; 可独立运行的 Application; 服务器端的 Servlet。 |
67.下列说法正确的有()(多选)
A | 环境变量可在编译source code时指定 | |
B. | 在編译程序时,所指定的环境变置不包括class path | |
C. | javac —次可同时编译数个Java 源文件 | |
D. | javac.exe能指定编译结果要置于哪个目录(directory) | |
答案:BCD 分析: 环境变量一般都是先配置好再编译源文件。 |
68.下列标识符不合法的有()(多选)
A | new | |
B. | $Usdollars | |
C. | 1234 | |
D. | car.taxi | |
答案:ACD 分析: new是Java的关键字; C. 数字不能开头; D. 不能有“.”。 |
69.下列说法错误的有()(多选)
A | 数组是—种对象 | |
B. | 数组属于一种原生类 | |
C. | int number[]=(31,23,33,43,35,63) | |
D. | 数组的大小可以任意改变 | |
答案:BCD 分析: B. Java中的原生类(即基本数据类型)有8种,但不包括数组; C. 语法错误,应该“{···}”,而不是“(···)”; D. 数组的长度一旦确定就不能修改。 |
70.不能用来修饰interface的有()(多选)
A | private | |
B. | public | |
C. | protected | |
D. | static | |
答案:ACD 分析: 能够修饰interface的只有public、abstract以及默认的三种修饰符。 |
71.下列正确的有()(多选)
A | call by value不会改变实际参数的数值 | |
B. | call by reference能改变实际参数的参考地址 | |
C. | call by reference 不能改变实际参数的参考地址 | |
D. | call by reference 能改变实际参数的内容 | |
答案:ACD 分析: Java中参数的传递有两种,一种是按值传递(call by value:传递的是具体的值,如基础数据类型),另一种是按引用传递(call by reference:传递的是对象的引用,即对象的存储地址)。前者不能改变实参的数值,后者虽然不能改变实参的参考地址,但可以通过该地址访问地址中的内容从而实现内容的改变。 |
72.下列说法错误的有()(多选)
A | 在类方法中可用this来调用本类的类办法 | |
B. | 在类方法中调用本类的类方法时可以直接调用 | |
C. | 在类方法中只能调用本类中的类方法 | |
D. | 在类方法中绝对不能调用实例方法 | |
答案:ACD 分析: 类方法是在类加载时被加载到方法区存储的,此时还没有创建对象,所以不能使用this或者super关键字; C. 在类方法中还可以调用其他类的类方法; D. 在类方法可以通过创建对象来调用实例方法。 |
73.下列说法错误的有()(多选)
A | Java面向对象语言容许单独的过栈与函数存在 | |
B. | Java面向对象语言容许单独的方法存在 | |
C. | Java语言中的方法属于类中的成员(member) | |
D. | Java语言中的方法必定隶属于某一类(对象),调用方法与过程或函数相同 | |
答案:ABC 分析: B. Java不允许单独的方法,过程或函数存在,需要隶属于某一类中; C. 静态方法属于类的成员,非静态方法属于对象的成员。 |
74.下列说法错误的有()(多选)
A | 能被java.exe成功运行的java class文件必须有main()方法 | |
B. | J2SDK就是Java API | |
C. | Appletviewer.exe可利用jar选项运行.jar文件 | |
D. | 能被Appletviewer成功运行的java class文件必须有main()方法 | |
答案:BCD 分析: B. J2SDK是sun公司编程工具,API是指的应用程序编程接口; C. Appletviewer.exe就是用来解释执行java applet应用程序的,一种执行HTML文件上的Java小程序类的Java浏览器; D. 能被Appletviewer成功运行的java class文件可以没有main()方法。 |
75.请问0.3332的数据类型是()
A | float | |
B. | double | |
C. | Float | |
D. | Double | |
答案:B 分析: 小数默认是双精度浮点型即double类型的。 |
76.Java接口的修饰符可以为()
A | private | |
B. | protected | |
C. | final | |
D. | abstract | |
答案:D 分析: 能够修饰interface的只有public、abstract以及默认的三种修饰符。 |
77.不通过构造函数也能创建对象么()
A | 是 | |
B. | 否 | |
答案:A 分析: Java创建对象的几种方式: (1) 用new语句创建对象,这是最常见的创建对象的方法。 (2) 运用反射手段,调用java.lang.Class或者 java.lang.reflect.Constructor类的newInstance()实例方法。 (3) 调用对象的clone()方法。 (4) 运用反序列化手段,调用java.io.ObjectInputStream对象的readObject()方法。 (1)和(2)都会明确的显式的调用构造函数;(3)是在内存上对已有对象的影印,所以不会调用构造函数;(4)是从文件中还原类的对象,也不会调用构造函数。 |
78.存在使i+1< i的数么?
78.存在使i+1< i的数么?
79.接口可否继承接口?抽象类是否可实现接口?抽象类是否可继承实体类?
接口可以继承接口,抽象类可以实现接口,抽象类可以继承实体类。
80.int与Integer有什么区别?
int是java提供的8种原始数据类型之一。Java为每个原始类型提供了封装类,Integer是java为int提供的封装类。int的默认值为0,而Integer的默认值为null,即Integer可以区分出未赋值和值为0的区别,int则无法表达出未赋值的情况,例如,要想表达出没有参加考试和考试成绩为0的区别,则只能使用Integer。在JSP开发中,Integer的默认为null,所以用el表达式在文本框中显示时,值为空白字符串,而int默认的默认值为0,所以用el表达式在文本框中显示时,结果为0,所以,int不适合作为web层的表单数据的类型。
在Hibernate中,如果将OID定义为Integer类型,那么Hibernate就可以根据其值是否为null而判断一个对象是否是临时的,如果将OID定义为了int类型,还需要在hbm映射文件中设置其unsaved-value属性为0。另外,Integer提供了多个与整数相关的操作方法,例如,将一个字符串转换成整数,Integer中还定义了表示整数的最大值和最小值的常量。
81.可序列化对象为什么要定义serialversionUID值?
SerialVersionUid,简言之,其目的是序列化对象版本控制,有关各版本反序列化时是否兼容。如果在新版本中这个值修改了,新版本就不兼容旧版本,反序列化时会抛出InvalidClassException异常。如果修改较小,比如仅仅是增加了一个属性,我们希望向下兼容,老版本的数据都能保留,那就不用修改;如果我们删除了一个属性,或者更改了类的继承关系,必然不兼容旧数据,这时就应该手动更新版本号,即SerialVersionUid。
82.写一个Java正则,能过滤出html中的< a href=”url”>title< /a>形式中的链接地址和标题.
< ab[^>]+bhref=”([^”]*)”[^>]*>([sS]*?)< /a>
< ab[^>]+bhref=”([^”]*)”[^>]*>([sS]*?)< /a>
83.十进制数72转换成八进制数是多少?
答: 110
84.Java程序中创建新的类对象,使用关键字new,回收无用的类对象使用关键字free正确么?
答:Java程序中创建新的类对象,使用关键字new是正确的; 回收无用的类对象使用关键字free是错误的.
85.Class类的getDeclaredFields()方法与getFields()的区别?
答:getDeclaredFields(): 可以获取所有本类自己声明的方法, 不能获取继承的方法
getFields(): 只能获取所有public声明的方法, 包括继承的方法
86.在switch和if-else语句之间进行选取,当控制选择的条件不仅仅依赖于一个x时,应该使用switch结构;正确么?
答:不正确。
通常情况下,进行比较判断的处理,switch 和if-else可以互相转换来写;if-else作用的范围比switch-case作用范围要大,但是当switch-case和if-else都可以用的情况下,通常推荐使用switch-case。
比如:
switch (ch) {
case 'a':
System.out.println("A");
break;
case 'b':
System.out.println("B");
break;
case 'c':
System.out.println("C");
break;
case 'd':
System.out.println("D");
break;
case 'e':
System.out.println("E");
break;
default:
System.out.println("other");
break;
}
换为if-else
if (ch == 'a') {
System.out.println("A");
} else if (ch == 'b') {
System.out.println('B');
} else if (ch == 'c') {
System.out.println("C");
} else if (ch == 'd') {
System.out.println("D");
} else if (ch == 'e') {
System.out.println("E");
} else {
System.out.println("Other");
}
87.描述&和&&的区别。
&和&&的联系(共同点):
&和&&都可以用作逻辑与运算符,但是要看使用时的具体条件来决定。
操作数1&操作数2,操作数1&&操作数2,
操作数1&操作数2,操作数1&&操作数2,
情况1:当上述的操作数是boolean类型变量时,&和&&都可以用作逻辑与运算符。
情况2:当上述的表达式结果是boolean类型变量时,&和&&都可以用作逻辑与运算符。
表示逻辑与(and),当运算符两边的表达式的结果或操作数都为true时,整个运算结果才为true,否则,只要有一方为false,结果都为false。
表示逻辑与(and),当运算符两边的表达式的结果或操作数都为true时,整个运算结果才为true,否则,只要有一方为false,结果都为false。
(1)、&逻辑运算符称为逻辑与运算符,&&逻辑运算符称为短路与运算符,也可叫逻辑与运算符。
对于&:无论任何情况,&两边的操作数或表达式都会参与计算。
对于&&:当&&左边的操作数为false或左边表达式结果为false时,&&右边的操作数或表达式将不参与计算,此时最终结果都为false。
综上所述,如果逻辑与运算的第一个操作数是false或第一个表达式的结果为false时,对于第二个操作数或表达式是否进行运算,对最终的结果没有影响,结果肯定是false。推介平时多使用&&,因为它效率更高些。
(2)、&还可以用作位运算符。当&两边操作数或两边表达式的结果不是boolean类型时,&用于按位与运算符的操作。
88.使用final关键字修饰符一个变量时,是引用不能变,还是引用的对象不能变?
final修饰基本类型变量,其值不能改变。
但是final修饰引用类型变量,栈内存中的引用不能改变,但是所指向的堆内存中的对象的属性值仍旧可以改变。
例如:
class Test {
public static void main(String[] args) {
final Dog dog = new Dog("欧欧");
dog.name = "美美";//正确
dog = new Dog("亚亚");//错误
}
}
89.请解释以下常用正则含义:d,D,s,.,*,?,|,[0-9]{6},d+
d: 匹配一个数字字符。等价于[0-9]
D: 匹配一个非数字字符。等价于[^0-9]
s: 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ fnrtv]
. :匹配除换行符 n 之外的任何单字符。要匹配 . ,请使用 . 。
*:匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 *。
+:匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 +。
|:将两个匹配条件进行逻辑“或”(Or)运算
[0-9]{6}:匹配连续6个0-9之间的数字
d+:匹配至少一个0-9之间的数字
90.已知表达式int m[] = {0,1,2,3,4,5,6}; 下面那个表达式的值与数组的长度相等()
A | m.length() | |
B. | m.length | |
C. | m.length()+1 | |
D. | m.length+1 | |
答案:B 分析:数组的长度是.length |
91.下面那些声明是合法的?()
A | long l = 4990 | |
B. | int i = 4L | |
C. | float f = 1.1 | |
D. | double d = 34.4 | |
答案:AD 分析:B int属于整数型应该是int=4 C应该是float f=1.1f |
92.以下选项中选择正确的java表达式()
A | int k=new String(“aa”) | |
B. | String str = String(“bb”) | |
C. | char c=74; | |
D. | long j=8888; | |
答案:CD 分析:A需要强制类型转换 B String str =new String(“bb”) |
93.下列代码的输出结果是
System.out.println(""+(""=="12"&&"12".equals("12")));
(“”==”12”&&”12”.equals(“12”))
“”==”12”&&”12”.equals(“12”)
true
false
94.以下哪些运算符是含有短路运算机制的?请选择:()
A | & | |
B. | && | |
C. | | | |
D. | || | |
答案:BD 分析:A C是逻辑与计算 |
95.下面哪个函数是public void example(){….}的重载函数?()
A | private void example(int m){…} | |
B. | public int example(){…} | |
C. | public void example2(){…} | |
D. | public int example(int m.float f){…} | |
答案:AD 分析:BC定义的是新函数 |
96.给定某java程序片段,该程序运行后,j的输出结果为()
int i=;
Int j=i++;
If((j>++j)&&(i++==j)){j+=i:}
System.out.println(j);
A | 1 | |
B. | 2 | |
C. | 3 | |
D. | 4 | |
答案:B 分析: i++先引用后。++i 先增加后引用 |
97.在java中,无论测试条件是什么,下列()循环将至少执行一次。
A | for | |
B. | do…while | |
C. | while | |
D. | while…do | |
答案:B 分析: ACD都不一定进行循环 |
98.打印结果:
package com.bjsxt;
public class smaillT{
public static void main(String args[]){
smaillT t=new smaillT();
int b = t.get();
System.out.println(b);
}
public int get()
{
try {
return;
}finally{
return;
}
}
}
输出结果:2
99.指出下列程序的运行结果
int i=;
switch (i) {
default:
System.out.println("default");
case:
System.out.println("zero");
break;
case:
System.out.println("one");
break;
case:
System.out.println("two");
break;
}
打印结果:
打印结果:
zero
100.解释继承、重载、覆盖。
继承(英语:inheritance)是面向对象软件技术当中的一个概念。如果一个类别A“继承自”另一个类别B,就把这个A称为“B的子类别”,而把B称为“A的父类别”也可以称“B是A的超类”。继承可以使得子类别具有父类别的各种属性和方法,而不需要再次编写相同的代码。在令子类别继承父类别的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类别的原有属性和方法,使其获得与父类别不同的功能。另外,为子类别追加新的属性和方法也是常见的做法。 一般静态的面向对象编程语言,继承属于静态的,意即在子类别的行为在编译期就已经决定,无法在执行期扩充。