我在定义一个final int类型的成员变量时,没有赋初始值,eclipse直接提示错误,dos编译也能通过,但是String类里面却又大量的没有给final定义的变量赋值的写法,这是为什么呢?public final class String
implements java.io.Serializable, Comparable<String>, CharSequence
{
/** The value is used for character storage. */
private final char value[]; /** The offset is the first index of the storage that is used. */
private final int offset; /** The count is the number of characters in the String. */
private final int count;String类中的被final修饰的offset变量貌似在源代码中几次被赋值,这又是为什么呢?还是我有什么没有理解的?string
implements java.io.Serializable, Comparable<String>, CharSequence
{
/** The value is used for character storage. */
private final char value[]; /** The offset is the first index of the storage that is used. */
private final int offset; /** The count is the number of characters in the String. */
private final int count;String类中的被final修饰的offset变量貌似在源代码中几次被赋值,这又是为什么呢?还是我有什么没有理解的?string
例如:
final A a = new A();
a.value = 2;
这样是可以的,但是如果再从新赋值a就报错了:a = new A();
this.offset = 0;
this.count = 0;
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) {
int size = original.count;
char[] originalValue = original.value;
char[] v;
if (originalValue.length > size) {
// The array representing the String is bigger than the new
// String itself. Perhaps this constructor is being called
// in order to trim the baggage, so make a copy of the array.
int off = original.offset;
v = Arrays.copyOfRange(originalValue, off, off+size);
} else {
// The array representing the String is the same
// size as the String, so no point in making a copy.
v = originalValue;
}
this.offset = 0;
this.count = size;
this.value = v;
}
他的设计理念是先申明,而不赋初值,这中变量叫final空白,但是在使用空白final之前必须被初始化,在构造函数里赋值了。
final类不能被继承,没有子类,final类中的方法默认是final的。
final方法不能被子类的方法覆盖,但可以被继承。
final成员变量表示常量,只能被赋值一次,赋值后值不再改变。
final不能用于修饰构造方法。 你疑惑的是第三条java的String类中成员变量offset使用final进行修饰。但并没有进行赋值。
你也就可以理解为offset是一个空白的身份证,每个构造方法是对身份证进行打印的操作。String类中有多个构造方法,每个方法中都对offset进行了赋值处理,一旦赋值一次就不能再进行修改了。
我们在创建一个对象时,只会调用类的一个构造方法去实例化,所以就不会出现final offset被赋值多遍的情况。
例如:
String str = new String(byte bytes[], int offset, int length);
String str1 = new String(byte bytes[], int offset, int length, Charset charset);另外需要注意的是,图片中被圈起的两个offset是不一样的。
一个是方法参数offset,一个是类成员变量offset(就是你说的 final offset)
但小弟还有个问题,我看到String类中有很多重载的构造方法,于是我也写了个重载的构造方法来给final变量赋值public class Test25_final {
private final int x;
public Test25_final(){
x = 5;
}
public Test25_final(int xx){
this.x = xx;
}
public static void main(String[] args){
Test25_final tf = new Test25_final();
System.out.println(tf.x);
Test25_final tf2 = new Test25_final(6);
System.out.println(tf2.x);
Test25_final tf3 = new Test25_final(7);
System.out.println(tf3.x);
}
}当我打印时分别打印了5,6,7。这是为什么,我第一次调用构造方法时已经给x赋值了,后面的构造方法还是有效果,并且重新给x赋值了。。这又为什么,或者又是我哪里理解错了? 这个x加不加都没有影响,那final在这个类中到底起作用了么?
这里你创建了3个Test25_final对象,每个对象都用重新初始化,也就是要重新调用构造方法,所以,所以你的final值会都不一样,因为他们彼此不相干。
用我上面的例子就是,你现在有3张空白的身份证,通过实例化构造方法去为身份证复制。
你new几次就决定你有几张身份证。
不知道你是否能明白。画了个图,参考下吧。
试试应该就不行了吧 。
Test25_final tf = new Test25_final();
System.out.println(tf.x);
Test25_final tf2 = new Test25_final(6);
System.out.println(tf2.x);
Test25_final tf3 = new Test25_final(7);
System.out.println(tf3.x);
这里你每次都new一个对象,每次new一个对象的时候都会重新调用构造函数,重新赋值的