java面试

java 传值

public static func(int a,String b,String c){
   a=a+1;
   b.trim()//去除字符串首尾的空字符
   c=b;
}
publci static void main(String[] args){
    int a = 0;
    String b = "Hello World";
    String c = "OK";
    func(a,b,c);
    System.out.println(""+a+","+b+","+c);
    }

这段程序的输出结果是: 0,Hello World,OK。
a显然是两个不同的局部变量,并且直接就是把值复制给函数参数变量,b和c虽然是引用类型,但是也是一样,把指针指向的地址复制给函数参数变量,但是都没有对其指向的数据进行修改。
改下代码再来分析

public static func(int a,String b,String c){
   a=a+1;
   b+="java";
   c=b;
}
publci static void main(String[] args){
    int a = 0;
    String b = "Hello World";
    String c = "OK";
    func(a,b,c);
    System.out.println(""+a+","+b+","+c);
    }

输出结果还是: 0,Hello World,OK。
重点在b+="java";这里是让函数的里的b变量指向了新的字符串Hello Worldjava。并没有改变原来指向的值。
那么要如何改变传进来的值呢,使用StringBuilder类。

package javabasic;

public class Delivery {

    public static void func(int a,StringBuilder b,StringBuilder c){
        a++;
        b.append("java");
        c.delete(0, 10);
        c.append("perfect");
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        int a = 0;
        StringBuilder b = new StringBuilder("Hello world");
        StringBuilder c = new StringBuilder("OK");
        func(a,b,c);
        System.out.println(a+","+b+","+c);
    }

}

字符串对象

以下创建了几个对象

String A ,B ,C;
A = "a";
B = "b";
A = A+B;
StringBuffer D =new StringBuffer("abc");
D = D.append("567");

我的答案是:”a” “b” “ab” “abc” “567” StringBuffer D, 总共6个

关于java 的字符串对象有两点要注意:
1.所有字符串常量都放在字符串池中,是不可以改变的。
String a = “abc”; String b = “abc”;
a , b 指向同一个对象。
2.创建字符串对象的方法有,用”” 或 new,new 出来的对象不会放到字符串池中。所以new String(“abc”);会创建两个对象(“abc”没有在字符串池中);

自己的理解是不对的,看下最新的解释,需要学过编译原理
首先, 明确一下 创建对象 的具体含义. 按我的理解, 如果字符串是 字符常量, 那么这个字符串对象是在编译时候确定好的, 它是存放在常量池中的, 因此就不算是创建了一个字符串对象, 而如果有 String b = new String(“abc”) 之类的操作, 那么可以认为是创建了字符串对象, 并与变量 b 关联.

根据上面的定义, 那么有: “a”, “b”, “abc”, “567” 都是常量, 放在常量池中的, 因此就不算是创建对象了.

那么来看一下代码:源码:

1: String a,b,c;
2: a = "a";
3: b = "b";
4: a = a+b;
5: StringBuffer d = new StringBuffer("abc");
6: d = d.append("567");

为了方便起见, 我手动给每一行编号了.再来看一下对应的字节码:

Code:
  stack=3, locals=5, args_size=1
     0: ldc           #2                  // String a
     2: astore_1
     3: ldc           #3                  // String b
     5: astore_2
     6: new           #4                  // class java/lang/StringBuilder
     9: dup
    10: invokespecial #5                  // Method java/lang/StringBuilder."<init>":()V
    13: aload_1
    14: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
    17: aload_2
    18: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
    21: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
    24: astore_1
    25: new           #8                  // class java/lang/StringBuffer
    28: dup
    29: ldc           #9                  // String abc
    31: invokespecial #10                 // Method java/lang/StringBuffer."<init>":(Ljava/lang/String;)V
    34: astore        4
    36: aload         4
    38: ldc           #11                 // String 567
    40: invokevirtual #12                 // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
    43: astore        4
    45: return

由字节码可以看出, 源码的第四行 a = a+b 翻译为如下代码:

StringBuilder builder = new StringBuilder();
builder.append(a);
builder.append(b);
a = builder.toString();

那么这里就新建了一个对象 new StringBuilder(), 接着调用 builder.toString() 方法, 它源码如下:

@Override
public String toString() {
    // Create a copy, don't share the array
    return new String(value, 0, count);
}

于是 builder.toString() 方法创建了一个 String 对象, 因此目前我们已经创建了 两个对象 了.

接着第五行 StringBuffer d = new StringBuffer(“abc”) 毫无疑问是 创建了对象 StringBuffer, 于是我们就有 三个对象 了. 有一点需要注意的是 StringBuffer d 从始至终都没有调用 toString 方法, 因此就不会有多余的 String 创建出来.

总结:

“a”: 字符串常量, 不算创建对象
“b”: 字符串常量, 不算创建对象
builder 对象: 在执行 a = a+b 时创建.
“ab”: 由 StringBuilder.toString() 创建.
“abc”: 字符串常量, 不算创建对象
“567”: 字符串常量, 不算创建对象
d: 通过 new StringBuffer(“abc”) 创建.
因此最终有三个对象创建了.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值