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

      无聊的问题总结.
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对象创建,因为执行这句话之前肯定要加载类,继而创建字符串字面量对应的对象,也就说执行这句话之前,"abc"已经存在了,这句话可以说是创建了一个String对象。但是,问问题的人可能根本不知道自己想问什么,所以答案可能是五花八门的了。】
  String str="a"+"b"+"c"+"d";
  这句话会创建几个对象?
  用SUN的jdk处理,经过javac编译之后,常量运算已经直接处理掉了,所以生成的class文件里的常量池表中有"abcd"这个串.(遵从java语言规范的编译器应该都是这个样子的)
所以执行这句话的时候,只会有一个对象.对于连编译和运行都分不清的人就不用多解释了.
  这个问题有人用组合的方法得出很多结论,后来看到有人说,Thinking in Java上介绍的,内部原理是用的StringBuilder来连接的,这里有2个问题,第一,如果这个例子会用StringBuilder来连接的话,那么String对象还是只有1个,第二,如果问一共有几个对象,再考虑StringBuilder来连接的问题的话,那这里面起码又带来了StringBuilder类对应的Class对象及其内部对象,这个数量就很大了.一个值得思考的问题是,既然能看到Thinking In Java中的结论,为什么不能看看TIJ中分析问题的思路呢.
顺便写点测试代码:

  1. publicclassMain{
  2. publicstaticvoidmain(Stringarg[]){
  3. Stringstr="a"+"b"+"c"+"d";
  4. }
  5. }

按照TIJ上的方法,也是我喜欢的方法:
javap -c Main

  1. Compiledfrom"Main.java"
  2. publicclassMainextendsjava.lang.Object{
  3. publicMain();
  4. Code:
  5. 0:aload_0
  6. 1:invokespecial#1;//Methodjava/lang/Object."<init>":()V
  7. 4:return
  8. publicstaticvoidmain(java.lang.String[]);
  9. Code:
  10. 0:ldc#2;//Stringabcd
  11. 2:astore_1
  12. 3:return
  13. }

可以看到,里面只有一个String abcd.
"a"+"b"+"c"+"d"都是常量的缘故,编译的时候就直接处理掉了,所以不会在运行的时候再通过StringBuilder来连接了.

  改变代码,换个例子:

  1. publicclassMain{
  2. publicstaticvoidmain(Stringarg[]){
  3. Strings="c";
  4. Stringstr="a"+"b"+s+"d";
  5. }
  6. }

  这个会出现几个String?
javap -c Main

  1. Compiledfrom"Main.java"
  2. publicclassMainextendsjava.lang.Object{
  3. publicMain();
  4. Code:
  5. 0:aload_0
  6. 1:invokespecial#1;//Methodjava/lang/Object."<init>":()V
  7. 4:return
  8. publicstaticvoidmain(java.lang.String[]);
  9. Code:
  10. 0:ldc#2;//Stringc
  11. 2:astore_1
  12. 3:new#3;//classjava/lang/StringBuilder
  13. 6:dup
  14. 7:invokespecial#4;//Methodjava/lang/StringBuilder."<init>":()V
  15. 10:ldc#5;//Stringab
  16. 12:invokevirtual#6;//Methodjava/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  17. 15:aload_1
  18. 16:invokevirtual#6;//Methodjava/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  19. 19:ldc#7;//Stringd
  20. 21:invokevirtual#6;//Methodjava/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  21. 24:invokevirtual#8;//Methodjava/lang/StringBuilder.toString:()Ljava/lang/String;
  22. 27:astore_2
  23. 28:return
  24. }


  可以发现这个例子中的String 有,"c","ab"(编译时对可确定的常量进行处理了),"d",以及最后通过StringBuilder.toString生成的String "abcd".
看书的意义是什么?起码不是背结论.
4.<java堆与栈>,一个垃圾帖子却被到处推荐来推荐去,很诡异的现象,很多人也喜欢给别人讲问题的时候引用,自己批评过一些,慢慢的感觉到没有必要了.原贴只是一个习作,貌似是作者初学的时候的一个总结,已经是若干年前的事情了,如果现在把原作者找出来让他自己看,估计也会出汗了.
    分析参考
http://zangxt.iteye.com/blog/440330
5.类的初始化顺序,这个实在没有必要讨论,自己运行一下就知道了,最笨的方法就是自己调试,单步跟踪,但也是收获最大的.

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

     分析参考http://zangxt.iteye.com/blog/461227

7.java的方法调用中,参数传递机制为pass by value.
很多人喜欢生造一个传引用的说法,但根本不知道传引用是什么意思.这点在<The Java Programming Language>(作者里有个人叫做James Gosling)上有详细和权威的说明,也说明了java为什么没有pass by reference ,<Core Java>中有内存图的说明,龙书<编译原理:技术与工具>第二版里面也有说明.其实真正把引用和对象两个概念理解了,也就不会有乱七八糟的说法了.如果不理解,记住!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值