Java学习笔记五

 

1Java’s finalkeyword has slightly different meanings depending on the context, but in general it says "This cannot be changed."

2A constant is useful for two reasons:
       It can be a compile-time constantthat won’t ever change.
      
It can be a value initialized at run time that you don’t want changed.

3In Java, these sorts of constants must be primitives and are expressed with thefinalkeyword. A value must be given at the time of definition of such a constant.

A field that is both staticandfinalhas only one piece of storage that cannot be changed.

When finalis used with object references rather than primitives, the meaning can be confusing. With a primitive,finalmakes thevaluea constant, but with an object reference,finalmakes the referencea constant. Once the reference is initialized to an object, it can never be changed to point to another object. However, the object itself can be modified; Java does not provide a way to make any arbitrary object a constant.

看个例子:

 

package access;

 

//: reusing/FinalData.java

//The effect of final on fields.

 

import java.util.*;

 

class Value {

inti;// Package access

 

public Value(int i) { this.i = i; }

}

 

public class FinalData {

privatestatic Randomrand =new Random(47);

private Stringid;

public FinalData(String id) {this.id = id; }

//Can be compile-time constants:

 

privatefinalintvalueOne = 9;

privatestaticfinalintVALUE_TWO = 99;

//Typical public constant:

 

publicstaticfinalintVALUE_THREE = 39;

//Cannot be compile-time constants:

 

privatefinalinti4 =rand.nextInt(20);

staticfinalintINT_5 =rand.nextInt(20);

private Valuev1 =new Value(11);

privatefinal Valuev2 =new Value(22);

privatestaticfinal ValueVAL_3 =new Value(33);

//Arrays:

 

privatefinalint[]a = { 1, 2, 3, 4, 5, 6 };

public String toString() {

returnid +": " +"i4 = " +i4 +", INT_5 = " +INT_5;

}

publicstaticvoid main(String[] args) {

FinalData fd1 = new FinalData("fd1");

//! fd1.valueOne++; // Error: can’t change value

//fd1.valueOne为final,所以不可以改变,参考这句话:

With a primitive, finalmakes thevaluea constant, but with an object reference,finalmakes the referencea constant. Once the reference is initialized to an object, it can never be changed to point to another object. However, the object itself can be modified;

fd1.v2.i++;// Object isn’t constant!

v2指向一个对象,对象可以改变,但v2本身不可变

fd1.v1 =new Value(9);// OK -- not final

 

for(int i = 0; i < fd1.a.length; i++)

fd1.a[i]++;// Object isn’t constant!

 

//! fd1.v2 = new Value(0); // Error: Can’t

不能更改v2所指向的对象

//! fd1.VAL_3 = new Value(1); // change reference

 

//! fd1.a = newint[3];

a实际指向一个数组的地址,所以不能改变其指向

System.out.println(fd1);

System.out.println("Creating new FinalData");

FinalData fd2 = new FinalData("fd2");

System.out.println(fd1);

System.out.println(fd2);

}

}

 

final参数:

Java allows you to make arguments final by declaring them as such in the argument list. This means that inside the method you cannot change what the argument reference points to 。

 

package access;

class Gizmo {

publicinti;

public Gizmo(int i)

{

this.i=i;

}

publicvoid spin() {

i=i+1;

System.out.println(i);

}

}

public class FinalArguments {

void with(final Gizmo g) {

//! g = new Gizmo(); // Illegal -- g is final

 

System.out.println("it is a final argument");

System.out.println(g.i);

g.i++;

System.out.println((g.i++));

System.out.println(g.toString());

}

void without(Gizmo g) {

g = new Gizmo(2);// OK -- g not final

 

System.out.println(g.toString());

g.spin();

}

// void f(finalint i) { i++; } // Can’t change

 

// You can only read from a final primitive:

 

int g(finalint i) {return i + 1; }

publicstaticvoid main(String[] args) {

FinalArguments bf = new FinalArguments();

Gizmo test = new Gizmo(2);

System.out.println(test.toString());

bf.without(test);

bf.with(test);

}

} ///:~

output:

access.Gizmo@5f155f15

access.Gizmo@5f705f70

3

it is a final argument

2

3

access.Gizmo@5f155f15

通过输出access.Gizmo@5f705f70可以看出在调用without函数的时候实际改变了指向。而由于在with函数中声明为final,对象所指向不能改变。

 

Final methond:put a "lock" on the method to prevent any inheriting class from changing its meaning. 关于代码优化的已经不是考虑的因素。

 

Any privatemethods in a class are implicitlyfinal :这句话我还迷惑了一会,注意这里说的是private方法,不是成员变量。

Final class

 

When you say that an entire class is final(by preceding its definition with thefinalkeyword), you state that you don’t want to inherit from this class or allow anyone else to do so.

 

static final变量在申明的时候就需要初始化。

static表示所有的类的对象共享一块内存区域,但是static的变量不一定是final的。

如果定义为static final则表示除了所有的对象共享一块内存区域外,还不能修改。

final变量则表示这个变量为常量,但是所有类的对象有各自的存储空间。

摘自Think in Java

Pitfall: “overriding” private methods:

Here’s something you might innocently try to do:
//: polymorphism/PrivateOverride.java
// Trying to override a private method.
package polymorphism;
import static net.mindview.util.Print.*;
public class PrivateOverride {
private void f() { print("private f()"); }
public static void main(String[] args) {
PrivateOverride po = new Derived();
po.f();
}
}
class Derived extends PrivateOverride {
public void f() { print("public f()"); }
} /* Output:
private f()
*///:~
You might reasonably expect the output to be “public f( )”, but a private method is automatically final, and is also hidden from the derived class. So Derived’s f( ) in this case is a brand new method; it’s not even overloaded, since the base-class version of f( ) isn’t visible in Derived.
The result of this is that only non-private methods may be overridden, but you should watch out for the appearance of overriding private methods, which generates no compiler warnings, but doesn’t do what you might expect. To be clear, you should use a different name from a private base-class method in your derived class.


static methods are associated with the class, and not the individual objects

记住一句话:constructors are not polymorphic (they’re actually static methods, but the static declaration is implicit)


 the order of constructor calls for a complex object is as follows:
1.
The base-class constructor is called. This step is repeated recursively such that the root of the hierarchy is constructed first, followed by the next-derived class, etc., until the most-derived class is reached.
2.
Member initializers are called in the order of declaration.

3.
The body of the derived-class constructor is called.


The order of disposal should be the reverse of the order of initialization, in case one subobject is dependent on another. For fields, this means the reverse of the order of declaration (since fields are initialized in declaration order). For base classes (following the form that’s used in C++ for destructors), you should perform the derived-class cleanup first, then the base-class cleanup.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

惹不起的程咬金

来都来了,不赏点银子么

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值