动力节点首页 全国咨询热线:400-8080-105

绑定手机号,登录
手机号

验证码

微信登录
手机号登录
手机号

验证码

30天自动登录
微信登录与注册
微信扫码登录与注册

扫码关注微信公众号完成登录与注册
手机号登录
首页 > 文章

Java基础学习细节

04-19 20:03 356浏览
举报 T字号
  • 大字
  • 中字
  • 小字

java基础有很多的细节,如果不清楚其底层是如何运行的,很多我们一贯以来的想法都会致使我们做出错误的判断,话不多说,一起来颠覆三观吧。

1. 猜猜他们分别会输出啥?

System.out.println(1+2+"a");
System.out.println("a"+1+2);

第一行输出3a,第二行输出a12

因为执行的时候是从左到右的,遇到字符串就会强转为字符串。

所以第一行执行的是:String str=String.valueOf(1+2); String sb=new StringBuffer(str).append("a").toString();

第二行执行的是: String sb=new StringBuffer("a").append("1").append("2").toString();

2. 那如果将上述题目改一下呢?

System.out.println(1+2+'a');
System.out.println('a'+1+2);

第一行输出100,第二行还是输出100

我们都知道,数据类型由低到高为byte/char/short< int < long < float < double,同时char类型向上转型会转化为相应的ASCII码,‘a'的ASCII码为97,故1+2+97输出100

3. 下面的语句有问题吗?

byte b1=1;
byte b2=2;
byte b3=b1+b2;

第三行会编译失败,原因在于对byte/short/char进行数值运算时,会强制转换为int类型,最终的结果也是int类型。

故正确的写法为 byte b3=(byte)(b1+b2)

4. 你觉得输出结果会是什么?

Integer i=128;
Integer j=128;
System.out.println(i==j);

false! why?Integer存在缓存机制,会自动将-128~127的integer对象缓存在Cache数组中,一旦调用Integer.valueOf(i)方法,且-128<=i<=127,则会自动到数组中拿出来,否则就会创建新的Integer对象

5. 他们相等吗?

String a="a";
String c=a;
System.out.println(a==c);

true!他们都是在常量池中,引用指向同一个地址

那这样呢?

String a="a";
String b="b";
String c="a"+"b";
System.out.println(a+b==c);
System.out.println("ab"==c);

false true why?首先String类型是不可变类型,那么第四行的执行如下:

a+b: new StringBuffer("a").append("b").toString();即在堆中新创建了一个对象,两者不再是同一个对象,但是编译器做了一些优化,在编译时期,String c="a"+"b"的编译结果是String c="ab".

6. 他们能交换吗?

public class Test{
    public static void main(String[] args){
        int a=1;
        int b=2;
        change(a,b);
        System.out.println(a+" "+b);
    }
    private static void change(int a, int b) {
        int c=a;
        a=b;
        b=c;
    }
}

输出结果为1 2

java的参数传递根据参数类型分为值传递和引用传递。基本数据类型及其包装类就是值传递,所以在change()方法中,a相当于一个局部变量,change()执行完毕即被销毁,原变量a并没有任何影响。

public class Test{
    public static void main(String[] args){
        AB ab=new AB(1, 2);
        change(ab);
        System.out.println(ab.a+" "+ab.b);
    }
    private static void change(AB ab) {
        int c=ab.a;
        ab.a=ab.b;
        ab.b=c;
    }
    static class AB{
        private int a;
        private int b;
        public AB(int a,int b) {
            this.a=a;
            this.b=b;
        }
    }
}

上述代码输出: 2 1,上述代码传递的是引用对象,所以是引用传递。即主函数的ab和change()方法中的ab共享同一个地址,因此在change()中交换数据会影响主函数中ab的参数。

7. 猜猜他们输出的结果分别是什么?

public class Test{
    public static void main(String[] args){
        String a="1";
        String b="2";
        change(a,b);
        System.out.println(a+" "+b);
    }
    private static void change(String a,String b) {
        a+="1";
        a=b;
    }
}

输出:1 2 原因在于对于String类型的对象,进行参数传递时也是值传递

public class Test{
    public static void main(String[] args){
        StringBuffer a=new StringBuffer("1");
        StringBuffer b=new StringBuffer("2");
        change(a,b);
        System.out.println(a+" "+b);
    }

    private static void change(StringBuffer a,StringBuffer b) {
        a.append(1);
    }
}

上述代码输出结果:11 2,得出这个答案无可厚非,关键是如果我们改一下呢?

private static void change(StringBuffer a,StringBuffer b) {
    a.append(1);
    a=b;
}

输出结果还是:11 2,这里就很有问题了,明明a=b,为什么还是输出11 2

原因在于:进行引用传递时,对原对象的引用是不会改变的。

我们再修改一下:

private static void change(StringBuffer a,StringBuffer b) {
    a=new StringBuffer("11");
}

最后打印结果还是:1 2,这样我们就可以总结一下了:实际上,java的参数传递只有值传递!但是便于理解,我们根据参数类型的不同分为值传递和引用传递,其中对于基本数据类型和不可变对象(包装类和String类)采取的是值传递,对于其他的引用类采取的是引用传递,引用传递可以在方法中修改原对象的内容,但是对原对象的引用始终不会改变!

0人推荐
共同学习,写下你的评论
0条评论
代码小兵865
程序员代码小兵865

6篇文章贡献51937字

相关课程 更多>

作者相关文章更多>

推荐相关文章更多>

Java面试题及答案整理

代码小兵66904-21 20:01

6道经典算法面试题

杨晶珍05-12 16:39

简述Spring MVC的核心组件

代码小兵49806-11 16:26

SpringMVC 中的组件

代码小兵49806-11 16:28

Spring常见面试题

代码小兵92504-17 16:07

发评论

举报

0/150

取消