Java中static和final总结 您所在的位置:网站首页 final不能用来修饰 Java中static和final总结

Java中static和final总结

2024-01-14 13:39| 来源: 网络整理| 查看: 265

目录1 final1.1 final总结1.2 使用final意义1.3 String中使用final2 static2.1 static总结2.2 理解Java的static import静态引入机制2.2.1 精确导入的方式2.2.2 按需导入的方式2.2.3 可以导入的种种东西2.2.4 导入之间的冲突问题2.2.5 本地和外来的竞争2.2.6 Static Import的负面影响2.3 java静态方法能否被重写

1 final 1.1 final总结 final修饰类:表示该类不可继承; final不能修饰interface接口 final修饰方法:表示该方法不能被子类覆盖(即子类不能重写父类的final方法,可以继承); final不能修饰构造函数 final修饰字段属性:表示属性值第一次初始化后不能被修改 final属性可以直接初始化或在构造函数中初始化,如果属性是直接初始化,则其值不能被其它函数(包括构造函数)修改 final修饰函数参数,参数值不能被函数修改 final修饰的 byte,short,char 型的值将被不会自动提升为int型,否则会自动提升为int型 byte b1=1,b2=2,b3; final byte b4=4,b5=5; b3=b4+b5;此行语句不会报错 final修饰函数中的局部变量,局部变量被第一次初始化后不能被修改 public void hello() { final String name; name = "hi"; //ok name = "hello"; //error } 1.2 使用final意义

使用final的意义:

为方法上锁,防止任何继承类改变它的本来含义和实现。设计程序时,若希望一个方法的行为在继承期间保持不变,而且不可被覆盖或改写,就可以采取这种做法。 提高程序执行的效率,将一个方法设成final后,编译器就可以把对那个方法的所有调用都置入嵌入调用里(内嵌机制)。 1.3 String中使用final

String中的final用法和理解

final StringBuffer a = new StringBuffer("111"); final StringBuffer b = new StringBuffer("222"); a=b;//此句编译不通过 final StringBuffer a = new StringBuffer("111"); a.append("222");// 编译通过

可见,final只对引用的值(即内存地址)有效,它迫使引用只能指向初始指向的那个对象,改变它的指向会导致编译期错误。至于它所指向的对象的变化,final是不负责的。

2 static 2.1 static总结 static修饰成员函数:该成员函数不能使用this对象 static不能修饰构造函数 static不能修饰函数参数 static不能修饰局部成员变量 static修饰成员字段 当类被虚拟机加载时,首先按照字段声明的先后顺序对static成员字段进行初始化 static修饰语句块 当类被虚拟机加载时,按照声明顺序先后初始化static成员字段和static语句块 static所修饰的方法和字段是只属于类,所有对象共享。 在static所修饰的函数和语句块中不能使用非static成员字段。 在Java不能直接定义全局变量,是通过static来实现的 在Java中没有const,不能直接定义常量,通过static final来实现 静态变量在编译期还是运行期加载,以及静态代码块加载的时机 当类加载器将类加载到JVM中的时候就会创建静态变量,这跟对象是否创建无关。静态变量加载的时候就会分配内存空间。静态代码块的代码只会在类第一次初始化的时候执行一次。一个类可以有多个静态代码块,它并不是类的成员,也没有返回值,并且不能直接调用。静态代码块不能包含this或者super,它们通常被用初始化静态变量 2.2 理解Java的static import静态引入机制

J2SE 1.5里引入了Static Import机制,借助这一机制,可以用略掉所在的类或接口名的方式,来使用静态成员。 在Java程序中,是不允许定义独立的函数和常量(当然,准确的说,只是被final修饰、只能赋值一次的变量)的。即使从它们本身的功能来看,完全不需要依附于什么东西,也要找个类或接口作为挂靠单位才行(在类里可以挂靠各种成员,而接口里则只能挂靠常量)。 挂靠的方法,是把它们加上static修饰符,定义为这个类或接口的静态成员。这方面的典型例子是java.lang.Math类——包含了大量的sin、cos这样的函数和PI、E这样的常量。 传统上,在访问这些挂靠了的函数、变量和常量的时候,需要在前面加上它们挂靠单位的名称。如果只是偶尔访问这些东西一下,这样的写法可以工作得很好;但是如果要频繁访问这些成员的话,这样的写法就显得比较罗嗦了。 J2SE 1.5里引入了Static Import机制,借助这一机制,可以用略掉所在的类或接口名的方式,来使用静态成员。 Static Import机制常常被直译成静态导入。但是从含义上看,静态成员导入是更为贴切的译法。不过考虑到静态导入这说法比较简短,估计还是会有强大的生命力。

有一种省去常量前的挂靠单位的变通做法:将所有的常量都定义到一个接口里面,然后让需要这些常量的类实现这个接口(这样的接口有一个专门的名目,叫作Constant Interface)。 这个方法可以工作。但是,因为这样一来,就可以从一个类实现了哪个接口推断出这个类需要使用哪些常量,有会暴露实现细节的问题。

2.2.1 精确导入的方式

精确的导入一个静态成员的方法,是在源文件的开头部分(任何类或接口的定义之前),加上类似这样的声明: import static 包名.类或接口名.静态成员名;

注意尽管这个机制的名目是叫做Static Import,但是在这里的次序却是正好相反的import static。一经导入之后,在整个源文件的范围内,就可以直接用这个成员的名字来访问它了。

用精确导入的方式,导入sin和PI

//精确的导入Math.sin和Math.PI import static java.lang.Math.sin; import static java.lang.Math.PI; public class StaticImportSampleA { public static void main(String[] args) { System.out.println(sin(PI/2));//输出“1.0” } }

Java语言并未要求每个类和接口都必须属于某一个包。但是,在J2SE 1.4以后,无论是import语句也好,还是import static语句也好,都要求给一个所在包名出来。换而言之,对于不属于任何包的类和接口,是既不能用import导入它本身,也不能用import static导入它的静态成员的。

2.2.2 按需导入的方式

Static Import机制也支持一种不必逐一指出静态成员名称的导入方式。这时,要采用这样的语法: import static 包名.类或接口名.*; 注意:这种方式只是指出遇到来历不明的成员时,可以到这个类或接口里来查找,并不是把这个类或接口里的所有静态成员全部导入。

用按需导入的方式,导入sin和PI

声明遇到来历不明的成员时到java.lang.Math中去寻找 import static java.lang.Math.*; public class StaticImportSampleB { public static void main(String[] args) { System.out.println(sin(PI/2));//输出“1.0” } } 2.2.3 可以导入的种种东西

使用import static语句,可以导入一个类里的一切被static修饰的东西,包括变量、常量、方法和内类。 变量、常量、方法和内部类都可以导入

package com.example.p3; public class StaticImportee { public static int one = 1; public static final int TWO = 2; public static int three() { return 3; } public static class Four { public int value() { return 4; } } } package com.example.p3; import static com.example.p3.StaticImportee.*; public class StaticImporter { public static void main(String[] args) { System.out.println(one); System.out.println(TWO); System.out.println(three()); System.out.println(new Four()); } }

不受影响的访问控制 Static Import不能突破Java语言中原有的访问控制机制的限制,不过也并不在这方面增加新的约束。原来有权限访问的静态成员,都可以被导入和使用;而原来无权限访问的静态成员,用了这个方法之后也仍然是访问不能。

2.2.4 导入之间的冲突问题

不同的类(接口)可以包括名称相同的静态成员。因此,在进行Static Import的时候,可能会出现两个语句导入同名的静态成员的情况。 在这种时候,J2SE 1.5会这样来加以处理:

如果两个语句都是精确导入的形式,或者都是按需导入的形式,那么会造成编译错误。 如果一个语句采用精确导入的形式,一个采用按需导入的形式,那么采用精确导入的形式的一个有效。 如果两个同名的静态成员一个是属性,而另一个是方法,那么因为使用时的写法有差异,不会造成任何的冲突。

采用精确导入的形式的一个有效

package com.example.p4; import static com.example.p4.Importee1.name; import static com.example.p4.Importee1.*; import static com.example.p4.Importee2.*; import static com.example.p4.Importee2.pass; public class Importer { public static void main(String[] args) { System.out.println(name);//输出“Name1” System.out.println(pass);//输出“Pass2” } } package com.example.p4; public class Importee1 { public static String name = "Name1"; public static String pass = "Pass1"; } package com.example.p4; public class Importee2 { public static String name = "Name2"; public static String pass = "Pass2"; } 2.2.5 本地和外来的竞争

有时候,导入的东西还可能和本地的东西相冲突,这种情况下的处理规则,是本地优先。 本地的优先于外来的

package com.example.p5; import static com.example.Zero.*; public class One { public static int flag = 1; public static void main(String[] args) { System.out.println(flag);//输出“1” } } package com.example.p5; public class Zero { public static int flag = 0; } 2.2.6 Static Import的负面影响

在编译期间,所有因Static Import的存在而简化了的名字,都会被编译器打回原型。因此在性能方面,Static Import没有任何影响。但是名字简化却可能造成一些维护方面的问题。 去掉静态成员前面的类型名,固然有助于在频繁调用时显得简洁,但是同时也失去了关于这个东西在哪里定义的提示信息,增加了阅读理解的麻烦。如果导入的来源很著名(比如java.lang.Math),或者来源的总数比较少,这个问题并不严重;但是在不属于这两种的情况下,这就不是基本可以忽略的问题了。

2.3 java静态方法能否被重写

JAVA静态方法形式上可以重写,但从本质上来说不是JAVA的重写。因为静态方法只与类相关,不与具体实现相关,声明的是什么类,则引用相应类的静态方法(本来静态无需声明,可以直接引用),看下例子:

class Base{ static void a( ){System.out.println("A"); } void b( ){System.out.println("B"); } } public class Inherit extends Base{ static void a( ){System.out.println("C"); } void b( ){System.out.println("D"); } public static void main(String args[]){ Base b=new Base(); Base c=new Inherit(); b.a(); b.b(); c.a(); c.b(); } } 以上输出的结果是:A B A D

非静态方法 按重写规则调用相应的类实现方法,而静态方法只与类相关。 所谓静态,就是在运行时,虚拟机已经认定此方法属于哪个类。 专业术语有严格的含义,用语要准确.重写只能适用于实例方法.不能用于静态方法.对于静态方法,只能隐藏(刚才的例子可以重写那只是形式上的 ,并不满足多态的特征,所以严格说不是重写)。 静态方法的调用不需要实例化吧.. 不实例化也就不能用多态了,也就没有所谓的父类引用指向子类实例.因为不能实例化 也就没有机会去指向子类的实例。所以也就不存在多态了。 点击此处查看重载和重写区别



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有