黑马程序员技术交流社区

标题: 今天的晚上的API考试第三题为什么选A啊? [打印本页]

作者: 花陌相惜    时间: 2016-7-30 22:14
标题: 今天的晚上的API考试第三题为什么选A啊?
public static void main(String[] args){
                String s1 = “abc”;
                String s2 = “xyz”;
show(s1,s2);
System.out.println(s1+”-----”+s2);
}
static void show(String s1,String s2){
         s1 = s2+s1+”Q”;     答案解释//show方法中的s1= “xyzabcQ”但是main函数中s1没有变化.
    s2 = “W”+s1;     //原理同上.
}
a) abc-----xyz
b) xyzabcQ-----xyzWabc
c) xyzabcQ---- xyzabcQWabc
d) xyzQ----Wabc
我记得如果那两个数为基本数据类型的话
int a=10;
int b=20;
show(int a,int b);
System.out.println(a+”-----”+b);   
这里打印的a,b是10,20,但是上面哪个不是引用数据类型吗?为什么打印出的值没有变啊?


作者: Oh_JAVA    时间: 2016-7-30 22:28
我也帮你回答一题..O(∩_∩)O哈哈~
JDK文档中,String类每一个看起来会修改String值的方法,实际上都创建了一个全新的String对象,以包含修改后的字符串内容.最初的String对象则丝毫未动
每当把String对象当做方法的参数时,都会复制一份引用
-----来自JAVA编程思想
作者: 花陌相惜    时间: 2016-7-30 22:36
Oh_JAVA 发表于 2016-7-30 22:28
我也帮你回答一题..O(∩_∩)O哈哈~
JDK文档中,String类每一个看起来会修改String值的方法,实际上都创建了一 ...

嗯嗯  看来还是要多看API帮助文档
作者: chenlongwen    时间: 2016-7-30 22:39
今天老师不高兴了
作者: Kaweh.    时间: 2016-7-30 22:41
注意 输出语句没有在show方法里边,因为字符串是常量,进show方法里 并没有改变实参的值
作者: Kingdragon    时间: 2016-7-30 22:45
String是特殊的类 完全可以把这种方式的String s = “adsaf”; 看成是常量 {存在于常量池中} 因为是final修饰
所以不会改变的  做连接时 相当于是在常量池中新创建了一个新的字符串
作者: 花陌相惜    时间: 2016-7-30 22:53
Kingdragon 发表于 2016-7-30 22:45
String是特殊的类 完全可以把这种方式的String s = “adsaf”; 看成是常量 {存在于常量池中} 因为是final ...

我知道String s = “adsaf”是存在于常量池中,final修饰没发现啊。。哪里有显示啊!
作者: Kingdragon    时间: 2016-7-30 22:56
花陌相惜 发表于 2016-7-30 22:53
我知道String s = “adsaf”是存在于常量池中,final修饰没发现啊。。哪里有显示啊! ...

你去看源码 String 中对字符串的操作实际是对字符数组的操作
作者: anywei    时间: 2016-7-30 22:59
这问题俺也是不会 有大神说String作为参数传递和基本数据类型一样 传递的是值 不是地址值
作者: Kingdragon    时间: 2016-7-30 23:00
花陌相惜 发表于 2016-7-30 22:53
我知道String s = “adsaf”是存在于常量池中,final修饰没发现啊。。哪里有显示啊! ...

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

    /** Cache the hash code for the string */
    private int hash; // Default to 0

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = -6849794470754667710L;
public String() {
        this.value = new char[0];
    }

    /**
     * Initializes a newly created {@code String} object so that it represents
     * the same sequence of characters as the argument; in other words, the
     * newly created string is a copy of the argument string. Unless an
     * explicit copy of {@code original} is needed, use of this constructor is
     * unnecessary since Strings are immutable.
     *
     * @param  original
     *         A {@code String}
     */
    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }

    /**
     * Allocates a new {@code String} so that it represents the sequence of
     * characters currently contained in the character array argument. The
     * contents of the character array are copied; subsequent modification of
     * the character array does not affect the newly created string.
     *
     * @param  value
     *         The initial value of the string
     */
    public String(char value[]) {
        this.value = Arrays.copyOf(value, value.length);
    }

    /**
     * Allocates a new {@code String} that contains characters from a subarray
     * of the character array argument. The {@code offset} argument is the
     * index of the first character of the subarray and the {@code count}
     * argument specifies the length of the subarray. The contents of the
     * subarray are copied; subsequent modification of the character array does
     * not affect the newly created string.
     *
     * @param  value
     *         Array that is the source of characters
     *
     * @param  offset
     *         The initial offset
     *
     * @param  count
     *         The length
     *
     * @throws  IndexOutOfBoundsException
     *          If the {@code offset} and {@code count} arguments index
     *          characters outside the bounds of the {@code value} array
     */
    public String(char value[], int offset, int count) {
        if (offset < 0) {
            throw new StringIndexOutOfBoundsException(offset);
        }
        if (count < 0) {
            throw new StringIndexOutOfBoundsException(count);
        }
        // Note: offset or count might be near -1>>>1.
        if (offset > value.length - count) {
            throw new StringIndexOutOfBoundsException(offset + count);
        }
        this.value = Arrays.copyOfRange(value, offset, offset+count);
    }

    /**
     * Allocates a new {@code String} that contains characters from a subarray
     * of the <a href="Character.html#unicode">Unicode code point</a> array
     * argument.  The {@code offset} argument is the index of the first code
     * point of the subarray and the {@code count} argument specifies the
     * length of the subarray.  The contents of the subarray are converted to
     * {@code char}s; subsequent modification of the {@code int} array does not
     * affect the newly created string.
     *
     * @param  codePoints
     *         Array that is the source of Unicode code points
     *
     * @param  offset
     *         The initial offset
     *
     * @param  count
     *         The length
     *
     * @throws  IllegalArgumentException
     *          If any invalid Unicode code point is found in {@code
     *          codePoints}
     *
     * @throws  IndexOutOfBoundsException
     *          If the {@code offset} and {@code count} arguments index
     *          characters outside the bounds of the {@code codePoints} array
     *
     * @since  1.5
     */
    public String(int[] codePoints, int offset, int count) {
        if (offset < 0) {
            throw new StringIndexOutOfBoundsException(offset);
        }
        if (count < 0) {
            throw new StringIndexOutOfBoundsException(count);
        }
        // Note: offset or count might be near -1>>>1.
        if (offset > codePoints.length - count) {
            throw new StringIndexOutOfBoundsException(offset + count);
        }

        final int end = offset + count;

        // Pass 1: Compute precise size of char[]
        int n = count;
        for (int i = offset; i < end; i++) {
            int c = codePoints;
            if (Character.isBmpCodePoint(c))
                continue;
            else if (Character.isValidCodePoint(c))
                n++;
            else throw new IllegalArgumentException(Integer.toString(c));
        }

        // Pass 2: Allocate and fill in char[]
        final char[] v = new char[n];

        for (int i = offset, j = 0; i < end; i++, j++) {
            int c = codePoints;
            if (Character.isBmpCodePoint(c))
                v[j] = (char)c;
            else
                Character.toSurrogates(c, v, j++);
        }

        this.value = v;
    }
这是部分源码
字段和构造方法
作者: 花陌相惜    时间: 2016-7-30 23:01
Kingdragon 发表于 2016-7-30 22:56
你去看源码 String 中对字符串的操作实际是对字符数组的操作

嗯呢 看到了  多谢
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

    /** Cache the hash code for the string */
    private int hash; // Default to 0

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = -6849794470754667710L;

    /**
作者: lynch123    时间: 2016-7-30 23:10
学到了,有空还的多看源码。
作者: HeiMa2Wangkunpe    时间: 2016-7-31 00:42
字符串虽然是引用数据类型  但是作为实际参数传递 其值不会发生改变
作者: 花陌相惜    时间: 2016-7-31 10:38
HeiMa2Wangkunpe 发表于 2016-7-31 00:42
字符串虽然是引用数据类型  但是作为实际参数传递 其值不会发生改变

实际参数传递不是基本数据类型吗?

作者: 东东瑞    时间: 2016-7-31 10:40
有回复的好的
作者: 花陌相惜    时间: 2016-7-31 10:42

我去  你就进来瞄瞄
作者: 18072727834    时间: 2016-8-1 21:30
多看源码  好处多多
作者: anyeyyc    时间: 2016-8-1 22:48
String 类型直接初始化的值存在常量池中
new出来的对象存在堆内存中  




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2