static静态,
final 不许修改和override
final 不许修改和override
解决方案 »
- [swing]表头的小三角图标?
- 关于自定义的classloader的问题。
- 问一个参数
- 在读别人一段代码的时候,遇到了一点不懂的问题。请大家帮忙:)
- 请问如何利用awt生成四个窗口,平分整个屏幕?
- JPanel的问题,高手快帮忙!!!(100分)
- socket.getInputStream().read(byteArray,position,lengh)是如何工作的???
- 请问那里有 Thinking in Java第三版的电子版可供下载???多谢
- 给分问题:如何展开JTree中的节点,内在细说……在线,解决即给分……
- 一个实际的迫在眉睫的问题
- 可不可以在某个类中设置另一个类的组件的值??
- 如何在java中调用matlab的算法?
final 表示的是最终的值。
给你举个简单的例子吧。
class A{
public static int COUNT1 = 0;
public final int COUNT2 = 1;
public A(){}
}
class B{
public static void main(String args[]){
A a1 = new A();
a1.COUNT1 = 2;
A a2 = new A();
System.out.println("a2.COUNT1 " + a2.COUNT1);//return 2 not 0;
//如果试图作下面的操作,会出现错误。
A.COUNT2 = 3;//因为COUNT2是final类型的,不能改变它的值。
}
}
static指静态
final指到了最后类,不能再有子类
final 不许修改和override
什么情况下我们要使用static呢?
1、只想用一个存储区域来保存一个特定的数据——无论要创建多少个对象,甚至根本不创 建对象。
2、我们需要一个特殊的方法,它没有与这个类的任何对象关联。也就是说,即使没有创建对象,也需要一个能调用的方法。
为满足这两方面的要求,可使用static(静态)关键字。
下面我先举个例子: 一旦将什么东西设为static,数据或方法就不会同那个类的任何对象实例联系到一起。所以尽管从未创建那个类的一个对象,仍能调用一个static方法,或访问一些static数据。
为了将数据成员或方法设为static,只需在定义前置和这个关键字即可。
例如,下述代码能生成一个static数据成员,并对其初始化:class StaticTest {
Static int i = 47;
}现在,尽管我们制作了两个StaticTest对象,但它们仍然只占据StaticTest.i的一个存储空间。这两个对象都共享同样的i。请考察下述代码:
StaticTest st1 = new StaticTest();
StaticTest st2 = new StaticTest();
此时,无论st1.i还是st2.i都有同样的值47,因为它们引用的是同样的内存区域。
有两个办法可引用一个static变量。正如上面展示的那样,可通过一个对象命名它,如st2.i。亦可直接用它的类名引用,而这在非静态成员里是行不通的(最好用这个办法引用static变量,因为它强调了那个变量的“静态”本质)。
StaticTest.i++;
其中,++运算符会使变量增值。此时,无论st1.i还是st2.i的值都是48。 类似的逻辑也适用于静态方法。既可象对其他任何方法那样通过一个对象引用静态方法,亦可用特殊的语法格式“类名.方法()”加以引用。静态方法的定义是类似的:
class StaticFun {
static void incr() { StaticTest.i++; }
}
从中可看出,StaticFun的方法incr()使静态数据i增值。可用典型的方法调用incr(): StaticFun sf = new StaticFun();
sf.incr();或者,由于incr()是一种静态方法,所以可通过它的类直接调用:
StaticFun.incr();
对方法来说,static一项重要的用途就是帮助我们在不必创建对象的前提下调用那个方法。
举简单一例如下:
public class TestStatic {
public static void main(String args[]){
PhoneCard mycard_1 = new PhoneCard();//创建第一张卡对象
PhoneCard mycard_2 = new PhoneCard();//创建第二张卡对象 mycard_1.addFee = 0.8;//给第一张卡的附加费addFee赋值为0.8
//注意到我们没有给第二张卡赋值
System.out.println("第一张卡的附加费:" + mycard_1.addFee);
System.out.println("第二张卡的附加费:" + mycard_2.addFee);
//发现没有?输出结果中第二张卡的附加费也是0.8 了。
System.out.println("卡的附加费:" + PhoneCard.addFee);
//该句的打印输出表明卡类的附加费都是0.8
}
} class PhoneCard{
static double addFee;//静态域addFee
}
该例创建了两个类,PhoneCard类只定义了一个变量,TestStatic类里创建了两个PhoneCard类对象,并给其中的一个对象的附加费addFee赋值,而另一个对象没赋值。由上例可以看出,静态域保存在类的公共存储单元,而不是保存在对象的存储单元内。static 修饰方法时是同理。
final可修饰类、域(变量和常量)、方法 (而static不修饰类)
1、final修饰类,表示该类不可被继承。
如定义了一个final类:
final class SnowBird{
int i;
String s;
static void fly(){
System.out.println("snowbird is flying");
}
}
//现在定义一个类,试图继承SnowBird类:
public class Bird extends SnowBird{
public static void main(String[] args){
SnowBird.fly();
}
}
把上面的两个类拷贝到文件中,文件名保存为Bird.java ,现在编译看看会出现什么问题?
出错信息是:cannot inherit from final SnowBird
表明final 类不可被继承。 那么,final修饰变量是怎么样呢?
2、final修饰变量
程序中经常需要定义各种类型的常量,如:3.24268,"201"等等。这时候我们就用final来修饰一个类似于标志符名字。如: final String connectNumber = "201";
final表明 connectNumber是一个常量,它的取值在整个过程都不会改变。
如果把final 去掉则connectNumber就成为变量了。有时我们为了节省空间,常量通常声明为 static .因为如上所说的 static 用的是类的内存空间。3、修饰方法:
final修饰的方法,称为最终方法。最终方法不可被子类重新定义,即不可被覆盖。
如父类定义了public void fly(){ ....}
则子类就不能定义
public void fly(){}
但注意覆盖与重载的区别。不能被覆盖并不是不能被重载,如你还可以定义
public void fly(int i){.....},
举个例子如下:
class FinalValue {
static final int i = 1;
final void fly(){
System.out.println("SnowBird is flying over FinalValue ");
}
} class TestFinal extends FinalValue {
int i = 2;
void fly(){
System.out.println("SnowBird is flying over TestFinal");
System.out.println("In class FinalValue static Final i = "+ FinalValue.i);
System.out.println("In class TestFinal i = "+ i);
}
void fly(String s){
System.out.println("fly("+ s + ")");
}
} public class Test {
public static void main(String args[]){
TestFinal tf = new TestFinal();
tf.fly();
tf.fly("ok");
System.out.println(tf.i);
}
}
把上面的程序保存为Test.java编译看看,出现什么错误?
然后,把TestFinal类中的 void fly(){ ... } 注解掉
即 如下
/* void fly(){
System.out.println("SnowBird is flying over TestFinal");
System.out.println("In class FinalValue static Final i = "+ FinalValue.i);
System.out.println("In class TestFinal i = "+ i);
}*/
现在再编译看看通过了吗? 可见重载与覆盖的区别了吧。 还发现 FinalValue中的 i 与 TestFinal中的 i 没关系 。因为对于变量而言,重定义只是父类的同名域被隐藏了而已。下面再举一个综合实例,回去仔细体会一下。(来源于Thinking in java)
static一样
//: c06:FinalData.java
// The effect of final on fields.class Value {
int i = 1;
}public class FinalData {
// Can be compile-time constants
final int i1 = 9;
static final int VAL_TWO = 99;
// Typical public constant:
public static final int VAL_THREE = 39;
// Cannot be compile-time constants:
final int i4 = (int)(Math.random()*20);
static final int i5 = (int)(Math.random()*20);
Value v1 = new Value();
final Value v2 = new Value();
static final Value v3 = new Value();
// Arrays:
final int[] a = { 1, 2, 3, 4, 5, 6 }; public void print(String id) {
System.out.println(
id + ": " + "i4 = " + i4 +
", i5 = " + i5);
}
public static void main(String[] args) {
FinalData fd1 = new FinalData();
//! fd1.i1++; // Error: can't change value
fd1.v2.i++; // Object isn't constant!
fd1.v1 = new Value(); // OK -- not final
for(int i = 0; i < fd1.a.length; i++)
fd1.a[i]++; // Object isn't constant!
//! fd1.v2 = new Value(); // Error: Can't
//! fd1.v3 = new Value(); // change reference
//! fd1.a = new int[3]; fd1.print("fd1");
System.out.println("Creating new FinalData");
FinalData fd2 = new FinalData();
fd1.print("fd1");
fd2.print("fd2");
}
} ///:~
// "Blank" final data members.class Poppet { }class BlankFinal {
final int i = 0; // Initialized final
final int j; // Blank final
final Poppet p; // Blank final reference
// Blank finals MUST be initialized
// in the constructor:
BlankFinal() {
j = 1; // Initialize blank final
p = new Poppet();
}
BlankFinal(int x) {
j = x; // Initialize blank final
p = new Poppet();
}
public static void main(String[] args) {
BlankFinal bf = new BlankFinal();
}
} ///:~
//: c06:Jurassic.java
// Making an entire class final.class SmallBrain {}final class Dinosaur {
int i = 7;
int j = 1;
SmallBrain x = new SmallBrain();
void f() {}
}//! class Further extends Dinosaur {}
// error: Cannot extend final class 'Dinosaur'public class Jurassic {
public static void main(String[] args) {
Dinosaur n = new Dinosaur();
n.f();
n.i = 40;
n.j++;
}
} ///:~
由于篇幅有限,你仔细研究下面的例子吧。
其实think in java里都有的。
//: c06:FinalOverridingIllusion.java
// It only looks like you can override
// a private or private final method.class WithFinals {
// Identical to "private" alone:
private final void f() {
System.out.println("WithFinals.f()");
}
// Also automatically "final":
private void g() {
System.out.println("WithFinals.g()");
}
}class OverridingPrivate extends WithFinals {
private final void f() {
System.out.println("OverridingPrivate.f()");
}
private void g() {
System.out.println("OverridingPrivate.g()");
}
}class OverridingPrivate2
extends OverridingPrivate {
public final void f() {
System.out.println("OverridingPrivate2.f()");
}
public void g() {
System.out.println("OverridingPrivate2.g()");
}
}public class FinalOverridingIllusion {
public static void main(String[] args) {
OverridingPrivate2 op2 =
new OverridingPrivate2();
op2.f();
op2.g();
// You can upcast:
OverridingPrivate op = op2;
// But you can't call the methods:
//! op.f();
//! op.g();
// Same here:
WithFinals wf = op2;
//! wf.f();
//! wf.g();
}
} ///:~
static 声明的变量通过类名直接调用,
final通常用来声明常量.
风往南刮,又往北转,不住的旋落,而且返回转行原道,江河都往海里转,海
却不满,江河从何处流,仍归何处。
final 表示的是最终的值。
给你举个简单的例子吧。
class A{
public static int COUNT1 = 0;
public final int COUNT2 = 1;
public A(){}
}
class B{
public static void main(String args[]){
A a1 = new A();
a1.COUNT1 = 2;
A a2 = new A();
System.out.println("a2.COUNT1 " + a2.COUNT1);//return 2 not 0;
//如果试图作下面的操作,会出现错误。
A.COUNT2 = 3;//因为COUNT2是final类型的,不能改变它的值。
}
}