您的位置:首页 > 编程语言 > Java开发

一些java中常见的基础问题的总结

2013-05-07 08:56 621 查看
己遇到过的一些总结一下,不断更新.

1.&和&&的区别.

java中的逻辑运算符:

& 逻辑与(AND)

| 逻辑或(OR)

^ 逻辑抑或(XOR)

! 逻辑非

&& 条件与(AND)

|| 条件或(OR)

注意&&和||会进行短路计算,第一个条件可以判断表达式的结果时,不对后面的条件进行判断了.

位操作运算符:

& 按位与(AND)

| 按位或(OR)

^ 按位抑或(XOR)

~ 按位取反

所以,问&和&&的区别时,千万别仅仅说一个是位操作符,一个是逻辑运算符.

2. short s=0;

s+=1;

正确,而

s=s+1;

不正确,为什么?

java中byte ,short,char之类的运算都是提升为int类型进行的,所以运算完之后要进行强制类型转换,复合赋值操作符编译器会自动添加强制转换操作.建议:尽量不要对byte,short,char这样的类型使用复合赋值运算符.

3.String str=new String(“abc”);

这句话创建了几个对象?

如果有人这么问问题,直接不要理会了,这个问题太难回答.不精通jvm的话还难精确的说会创建很多对象.自己目前能想到的,比如String类型对应的Class对象,这个Class内部的对象就好多个,可以去看Class类的源代码.

如果问创建了多少个String对象,那起码还好说点,首先对于”abc”,如果常量池中已经有了的话,那就不用创建了,如果没有肯定要解析常量池,并创建String对象,进行intern()操作.所以这里肯定会存在一个常量池里的对象.new String(“abc”);当然会导致在堆中创建一个对象.这里自己也不知道答案该如何归纳,1个或2个?等深入的学习一下再总结.

String str=”a”+”b”+”c”+”d”;

这句话会创建几个对象?

用SUN的jdk处理,经过javac编译之后,常量运算已经直接处理掉了,所以生成的class文件里的常量池表中有”abcd”这个串.

所以执行这句话的时候,只会有一个对象.对于连编译和运行都分不清的人就不用多解释了.

这个问题有人用组合的方法得出很多结论,后来看到有人说,Thinking in Java上介绍的,内部原理是用的StringBuilder来连接的,这里有2个问题,第一,如果这个例子会用StringBuilder来连接的话,那么String对象还是只有1个,第二,如果问一共有几个对象,再考虑StringBuilder来连接的问题的话,那这里面起码又带来了StringBuilder类对应的Class对象及其内部对象,这个数量就很大了.一个值得思考的问题是,既然能看到Thinking
In Java中的结论,为什么不能看看TIJ中分析问题的思路呢.

顺便写点测试代码:

public class Main{ public static void main(String arg[]){

String str=”a”+”b”+”c”+”d”; }

}

按照TIJ上的方法,也是我喜欢的方法:

javap -c Main

Compiled from “Main.java” public class Main extends java.lang.Object{

public Main(); Code:

0: aload_0 1: invokespecial #1; //Method java/lang/Object.””:()V

4: return

public static void main(java.lang.String[]); Code:

0: ldc #2; //String abcd 2: astore_1

3: return

}

可以看到,里面只有一个String abcd.

“a”+”b”+”c”+”d”都是常量的缘故,编译的时候就直接处理掉了,所以不会在运行的时候再通过StringBuilder来连接了.

改变代码,换个例子:

public class Main{ public static void main(String arg[]){

String s=”c”; String str=”a”+”b”+s+”d”;

} }

这个会出现几个String?

javap -c Main

Compiled from “Main.java” public class Main extends java.lang.Object{

public Main(); Code:

0: aload_0 1: invokespecial #1; //Method java/lang/Object.””:()V

4: return

public static void main(java.lang.String[]); Code:

0: ldc #2; //String c 2: astore_1

3: new #3; //class java/lang/StringBuilder 6: dup

7: invokespecial #4; //Method java/lang/StringBuilder.””:()V 10: ldc #5; //String ab

12: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 15: aload_1

16: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 19: ldc #7; //String d

21: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 24: invokevirtual #8; //Methodjava/lang/StringBuilder.toString:()Ljava/lang/String;

27: astore_2 28: return

}

可以发现这个例子中的String 有,”c”,”ab”(编译时对可确定的常量进行处理了),”d”,以及最后通过StringBuilder.toString生成的String “abcd”.

看书的意义是什么?起码不是背结论.

4.,一个垃圾帖子却被到处推荐来推荐去,很诡异的现象,很多人也喜欢给别人讲问题的时候引用,自己批评过一些,慢慢的感觉到没有必要了.原贴只是一个习作,貌似是作者初学的时候的一个总结,已经是若干年前的事情了,如果现在把原作者找出来让他自己看,估计也会出汗了.

有位老师总结了一下,感觉很好: http://topic.csdn.net/u/20081127/23/bd9ca56e-44d3-4f94-80f7-88f469f6dd79.html
5.类的初始化顺序,这个实在没有必要讨论,自己运行一下就知道了,最笨的方法就是自己调试,单步跟踪,但也是收获最大的.

6.以前总有人说,private 的方法默认是final的,后来又有人说static 方法默认也是final.第一个创造这个说法的人可能是为了让自己理解一些东西方便一些,但是慢慢就认为是真理了。

7.多态与重载什么关系?

可以说没有关系.但是很多面试别人的人自己都不理解,这个实在没招,但是你可以清晰的给他介绍重载和覆盖的适用范围.

多态性是面向对象的基本特性,重载在本质上是和面向对象没有关系的.(当然重载也可以发生在子类和父类的名字相同,签名不同的方法之间) 多态是和override密切相关的.

以前自己也犯过错误,认为重载是静态绑定的,在C++里这么说是没有问题的,但在java中不能这么说,因为对于重载而言,虽然编译的时候可以根据签名确定方法,但具体调用那个方法(跟java对覆盖的支持方式有关),还是要运行时来确定的.

8.java的方法调用中,参数传递机制为pass by value.

很多人喜欢生造一个传引用的说法,但根本不知道传引用是什么意思.这点在上有详细和权威的说明,也说明了java为什么没有pass by reference ,中有内存图的说明,龙书第二版里面也有说明.其实真正把引用和对象两个概念理解了,也就不会有乱七八糟的说法了.如果不理解,记住!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: