Java易错题
1.
public class ValuePass {
private static int a;
public static void main(String [] args) {
modify(a);
System.out.println(a);
}
public static void modify(int a) {
a++;
}
}
本程序的输出为0,因为a++是对形式参数进行自增,而不是类属性a进行自增。
2.
for (int i ; i < 3 ; i++ )
{
System.out.println(i); The local variable i may not have been initialized
}
局部变量使用前必须进行初始化赋值操作。(区分C/C++)
3. 两个整数相加,结果默认转化为int,赋值给byte或short时会发生类型转化问题。例如下面的代码b+c的结果必须进行显式转化。
public static void main(String[] args) {
byte b = 27;
byte c = 26;
byte d = b + c; //Type mismatch: cannot convert from int to byte
}
//正确的为:byte d = (byte)(b + c);
4.
例: float f = 3.2;
应改为float f = 3.2f; 或float f = (float)3.2;
5.
char ch = ‘\u1f1a0’; //错误
char ch = ‘\u0041’; //正确 System.out.println(ch); // A
‘\u????’的Unicode形式的字符,其中“????”应严格按照四个16进制数字进行替换,
String str = “Hello\u0041\n”; // 定义一个字符串变量,初值为HelloA
6.
boolean b = 1; // Type mismatch: cannot convert from int to boolean
boolean 类型只允许使用 boolean 值。
7.
Integer varInteger1 = 100 ; //自动装箱
Integer varInteger2 = Integer.valueOf(100);
System.out.println(varInteger1 == varInteger2);
//上述代码运行结果是什么?true
//如果把100改为1000,结果又是什么?false,但是此时varInteger1和varInteger2均为1000
//Integer默认会在-128到127(高频数值)之间复用已有的缓存对象,以提高性能。
8.
public class LogicAnd {
public static void main(String[] args){
int out = 10;
boolean b1 = false;
if ((b1 == true) && (out += 10) ==20){
System.out.println("相等,out="+out);
} else {
System.out.println("不等,out="+out);
}
}
}
//输出为不等,out=10,&&具有短路效应
//若将&&改为&呢? 输出为不等,out=20
9.
class Test{
public static void main(String[] args){
float sum=1.5f; int num=2;
System.out.println((sum < 2 ? 1 : num/sum));
}
}
//程序返回结果是1.0,而不是1,因为sum是浮点数,所以表达式2发生了数据的隐式转化。
10. 条件表达式中的结果应为布尔值,而不能为算术值。
例如while (y–) {x–;}是错误的
11.
public class Delta {
static boolean foo(char c) {
System.out.print(c);
return true;
}
public static void main( String[] argv ) {
int i =0;
for ( foo(‘A’); foo(‘B’)&&(i<2); foo(‘C’)){
i++ ;
foo(‘D’);
}
}
}
//结果输出为:ABDCBDCB
//for语句执行时,首先执行初始化操作,然后判断终止条件是否满足,如果满足,则执行循环体中的语句,最后执行迭代部分。完成一次循环后,重新判断终止条件。
12. 数组声明时不可在方括号内指定数组大小,如int [10] arr; 是错误的
13. 下面的写法是错误的: int[] a ; a= {3,4,5,6};
14.
//隐式使用super调用父类的构造方法
class Pare {
int i=3;
Pare(){ i=6;System.out.println("call super()");}
}
class Construct extends Pare{
int i = 10;
Construct(){System.out.println("execute Construct()");}
Construct(int num){this();System.out.println("execute Construct(int)");}
public static void main(String[] args){
Construct ct = new Construct(9);
System.out.println(ct.i);
}
}
//输出结果为:call super()
// execute Construct()
// execute Construct(int)
// 10
15.
String类对equals方法进行了覆盖,比较两个字符串对象的内容是否相等,而不是比较引用是否指向同一个字符串对象
String s1 = new String("Hello");
String s2 = new String("Hello");
System.out.println(s1.equals(s2));//true
//对象引用比较
String s1 = new String("Hello");
String s2 = new String("Hello");
System.out.println(s1==s2); //false
16.
String s1 = "abc";
String s3 = "abc";
String s2 = new String(“abc");
String s4 = new String(“abc");
System.out.println(s1==s2); // false
System.out.println(s1==s3); // true
System.out.println(s1.equals(s3)); // true
System.out.println(s2==s4); // false
System.out.println(s2.equals(s4)); // tru
17.
public class Str {
public void changePara(String s){
s = s +"a";
}
public void invoke(){
String s ="b";
changePara(s);
System.out.println(s); // 运行结果:b
}
public static void main(String[] str){
Str s = new Str();
s.invoke();
}
}
public class Str {
public void changePara(StringBuffer s){
s = s.append("a");
}
public void invoke(){
StringBuffer s =new StringBuffer("b");
changePara(s);
System.out.println(s);//执行结果:ba
}
public static void main(String[]str){
Str s = new Str();
s.invoke();
}
}
18.
public class StringExample {
public static void main(String[] args) {
String s1 = new String("abc");
s1 = s1.replace("a","A");
s1 = s1.concat("def");
System.out.println(s1); //Abcdef
}
}
public class StringExample {
public static void main(String[] args) {
String s1 = new String("abc");
s1.replace("a","A");
s1.concat("def");
System.out.println(s1); //abc
}
}
19.
import java.util.*;
public class TestSort{
public static void main(String[] args){
List al = new ArrayList();
al.add(new Integer(1));
al.add(new Integer(4));
al.add(new Double(2.5));
for(int i=0; i<3;i++){
Integer inte = (Integer)al.get(i);
System.out.println(inte);
}
}
//运行结果:
//1
//4
//Exception in thread "main" java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer
20.
HashMap原理
-HashMap
内部实现基于哈希表,采用链表法解决哈希冲突
- HashMap初始化和动态扩容(减少哈希冲突)
默认容量为16,默认装载因子为0.75
如果扩容,则扩容至原来哈希表大小的2倍
- 当哈希表中链表过长时(大于等于8),链表会转换为红黑树,提高性能
- HashMap是非线程安全的
- 当使用自定义对象作为Key时,需同时覆写hashCode和equals方法,确保Key的唯一性
21. Java语言有哪些特点?
(1)简单:简单而高效,Java系统(编译器和解释器)所占空间不到250KB。
(2)面向对象:是纯面向对象的语言。
(3)平台无关性与可移植性:可以在不同操作系统上运行。它既是编译型也是解释型语言。
(4)稳定性和安全性:摒弃了C++中的不安全因素——指针数据类型。保证字节码文件加载的安全和访问系统资源的安全。
(5)多线程并且是动态的:多线程使应用程序可以同时进行不同的操作和处理不同的时间。在执行过程中可以动态加载各类库,这一特点使之非常适合于网络运行,同时也非常有利于软件的开发,即使更新类库也不必重新编译使用这一类库的应用程序。
(6)高性能:通常解释型语言的执行效率要低于直接执行机器码的速度,但Java的字节码转换成机器码非常简单和高效。
(7)分布式:物理上分布,逻辑上统一。其内容包括数据分布和操作分布两个方面。数据分布是指数据可以分散存放于网络上的不同主机中,以解决海量数据的存储问题;操作分布则是指把计算分布到不同主机上进行处理,这就如同许多人协同共同完成一项大而复杂的工作一样。
22. final修饰符都有什么作用?
(1)Java中final修饰符既可以修饰类、方法,也可以修饰变量
(2)用final修饰的类不能被继承
(3)用final修饰的方法不可重写
(4)用final修饰的变量必须初始化,且之后不能赋值
23. static修饰的属性和方法有什么特点?
static修饰属性或方法后,属性和方法不在属于某个特定的对象,而是所有共享,也可以说是static成员不依赖某个对象,在类加载时就被初始化。static修饰的属性或方法,可以直接使用类名调用,而不用先实例化对象再调用。
24. 覆写与重载的区别
覆写:方法名称相同,参数类型、个数一致,子类返回类型可向上转型到. 父类返回类型 (类族)
重载:方法名称相同,参数类型或个数不同 (同一个类)
25. 封装、继承和多态在面向对象设计中的用途是什么?
(1)封装可以保护类的数据成员,隐藏信息。
(2)子类继承父类的属性和方法后,不用重新编写代码,提高了代码复用性。
(3)多态最重要的是子类的功能可以被父类的引用调用,向后兼容。
26. 接口有什么作用?
接口最直接的好处就是提供了一个统一的操作方法名,然后同样的方法名在不同的类中可以有不同的具体实现过程,这样的结果就是在操作实现了该接口的类的对象时,不用去事先了解该方法的名字,而采用统一的名字进行调用。
27. 抽象类与接口的异同点是什么?
相同点:
(1)不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。
(2)都有自己的声明,可以引用子类或实现类对象
不同点 :
(1)抽象类可以有域变量,接口没有,只能是静态常量。
(2)抽象类可以有具体方法;接口全是抽象方法。
(3)抽象类实现靠子类继承,接口靠实现类。
28. 引用比较方法有哪些?
(1)equals方法比较。
(2)使用“==”进行比较。
(3)使用instanceof比较引用类型
29. 内部类的作用是什么?什么情况下使用匿名内部类?
作用:
(1)内部类可以很好的实现隐藏。一般的非内部类,是不允许有 private 与protected权限的,但内部类可以。
(2)内部类拥有外围类的所有元素的访问权限。
(3)可实现多重继承。
(4)可以避免修改接口而实现同一个类中两种同名方法的调用。
匿名内部类:
匿名内部类是内部类的一种特殊情况。它只有一个实例,而且没有引用。所以,一般在能用内部类实现,但是实例只用一次的情况下使用它(可以减少资源开销)
30. String类型有什么特点?
(1)一旦赋值,便不能更改其指向的字符对象
(2)如果更改,则会指向一个新的字符对象
(3)不能为null
31. String与StringBuffer的区别是什么?如何相互转化?
StringBuffer是一个具有对象引用传递特点的字符串对象。
//数据类型由String转为StringBuffer
String s = “hello”;
StringBuffer sb = new StringBuffer(s); //调用的构造函数
//String也有相反的构造函数
String a = new String(sb);
//还可以用StringBuffer的一个方法
String str = sb.toString() ;
32. 线程和进程的联系和区别是什么?
区别:
(1)进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动,它是系统进行资源分配和调度的一个独立单位。
(2)线程是进程的一个实体,是CPU调度和分配的基本单位。线程基本不拥有系统资源,与同一个进程的其他线程共享进程中所拥有的所有资源。
联系:
一个进程可以包括多个线程。
33. 创建线程有几种方法?它们之间的区别是什么?
第一种方式:使用Runnable接口创建线程
(1)可以实现多个线程资源共享
(2)线程体run()方法所在的类可以从其它类中继承一些有用的属性和方法
第二种方式:直接继承Thread类创建对象
(1)Thread子类无法再从其它类继承(java语言单继承)。
(2)编写简单,run()方法的当前对象就是线程对象,可直接操作。
34.
定义一个复数类并按照复数的实部大小对复数对象进行排序。
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
class Plural{
private double x;
private double y;
public double getX() {return x;}
public void setX(double x) {this.x = x;}
public double getY() {return y;}
public void setY(double y) {this.y = y;}
public Plural() {x = 0; y = 0;}
public Plural(double x, double y) {this.x = x; this.y = y;}
public void show() {
if (y == 0)
System.out.println(x);
else if(y<0)
System.out.println(x + " - " + -y + "i");
else
System.out.println(x + " + " + y + "i");
}
}
class PluralComparator implements Comparator<Plural> {
//Comparator接口因为有2个参数,所以要单独写一个类
//而Comparable接口是一个参数,可以写到上面那个类,直接实现接口,这里没有用
@Override
public int compare(Plural o1, Plural o2) {
return o1.getX() < o2.getX() ? 1 : -1;
}
}
public class test {
public static void main(String[] args) {
ArrayList<Plural> lst = new ArrayList<>();
lst.add(new Plural(0, 2.3));
lst.add(new Plural(-5, 4));
lst.add(new Plural(-1.2, -3));
lst.add(new Plural(1, 0));
Collections.sort(lst, Collections.reverseOrder(new PluralComparator()));
//获取要不要交换
for(Plural p : lst)
p.show();
}
}
35. Java实现跨平台的解决措施
将源程序编译成字节码文件——扩展名为.class。这个二进制代码文件与具体操作系统的机器指令无关,其运行必须借助解释执行系统动态翻译成所在操作系统的机器码(由运行环境当中的Java虚拟机完成解释执行工作)。
36.
public class test {
public static String out = "";
public static void foo(int i)
{
try {
if(i==1){throw new Exception();}
out+="1";
}
catch (Exception e){
out+="2";
return;
}
finally {
out+="3";
}
out+="4";
}
public static void main(String[] args) {
foo(0);
foo(1);
System.out.println(test.out);
}
}
//程序输出为:13423
37. Collection是接口,Collections是类