您的位置:首页 > 编程语言 > Java开发

java:final和static初学

2016-05-22 20:34 435 查看
package com.jvmfinalstatic;

参考文献:http://lavasoft.blog.51cto.com/62575/18771/
/*本节学习java中的final关键字
* 1.final 从字面上理解:最后的,无可改变的、也就是有些API中的“终态”;
* 2.final修饰不同东西的不同效果
*  2.1修饰类
*      final类不能被继承,如果这个类不需要有子类,类也不想再扩展了就可以定义为final的;
*      final类中成员 域:
*          其域可以是 final 的也可以 不是final的 根据需求定义即可;
*      final类中成员 方法:
*          因此final类的成员方法没有机会被覆盖,默认都是 final 的。
*      示例代码:示例2.1
*  2.2修饰成员变量:
*      final修饰基本数据类型变量(局部变量):
*          用final修饰的成员变量表示常量,值一旦给定就无法改变!
*          final变量定义的时候,可以先声明,而不给初值,这中变量也称为final空白,
*          无论什么情况,编译器都确保空白final在使用之前必须被初始化.
*      final修饰引用变量:
*          则对其初试化之后就不能再指向另一个对象;引用不可以改变,但是它所指向的对象的内容可以改变
*      final小贴士:
*          public static final int VALUE_THREE = 39;
*          VALUE_THREE是一种更加典型的对常量进行定义的方式:定义为public,可以被任何人访问;定义为static,
*          则强调只有一份;定义为fianl,这说明它是个常量。请注意带有恒定初始值(即,编译期常量)
*          的final static基本类型全用大写字母命名,并且字母与字母之间用下划线隔开。
*
*  2.3修饰参数:
*      1.java中允许在参数列表中以声明的方式将参数指明为final,这就意味着无法在方法中更改参数引用所指向的对象;
*      2.匿名内部类的应用;
*  2.4修饰方法:
*      1.不让继承了修改它的含义;即不可以被覆盖
*      2.效率高点;
*  2.5final和private
*      1.类中的private方法隐式地指定为final的,由于无法取用private方法,所以也就无法覆盖它,因此对private方法
*        添加final修饰符什么作用也不起;
*
* 3.java中的static用法:
*  3.1static修饰的成员变量和成员方法
*      它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内
*      定找到他们。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。
*      静态变量:对于静态变量在内存中只有一个拷贝,JVM只为静态分配一次内存,在加载类的过程中完成静态变量的内存分配,
*      可用类名直接访问。
*      静态方法:静态方法可以直接通过类名调用,任何的实例也都可以调用,因此静态方法中不能用this和super关键字,不能直
*      接访问所属类的实例变量和实例方法(就是不带static的成员变量和成员成员方法),只能访问所属类的静态成员变量和成员
*      方法。因为实例成员与特定的对象关联!
*  3.2用public修饰的static成员变量和成员方法本质是全局变量和全局方法,(java中没有全局变量的定义)当声明它类的对象市,
*      不生成static变量的副本,而是类的所有实例共享同一个static变量。
*  3.3static变量前可以有private修饰,表示这个变量可以在类的静态代码块中,或者类的其他静态成员方法中使用,但是不能
*      在其他类中通过类名来直接引用,这一点很重要。
*  3.4 用static修饰的代码块表示静态代码块,当Java虚拟机(JVM)加载类时,就会执行该代码块
*

*
* */
//示例类2.1
final class FinalClass{
int noFinalField = 2;
final int finalField = 4;
public void  show(){
System.out.println("i was a default final method ,because the class name is modified by final keyword"+" :"+noFinalField);
}

}
/*class SonFinalClass extends FinalClass{
// Error:The type SonFinalClass cannot subclass the final class FinalClass
//remove the final modifier of FinalClass
}*/

//示例类2.2
class FinalField{
//第一种情况:a 为常量
private final int a = 10;
//第二种情况:final空白;
private final int b ;
//第三种情况:c: 一个即是static又是fianl的域只占一段不能改变的存储空间,将用大写表示
public static final int C =20;

FinalField(int b){
this.b=b;
System.out.println("a:"+a+" b:"+b+" c:"+C);
}
//第四种情况:
public void importMethod1(){
String a = "hello2";
final String b = "hello";
String c = "hello";
String d = b + 2;
String e = c + 2;
System.out.println((a == d));//true
System.out.println((a == e));//flase;
/*这里面就是final变量和普通变量的区别了,当final变量是基本数据类型以及String类型时,
* 如果在编译期间 能知道 它的确切值,则编译器会把它当做编译期常量使用。也就是说在用到该final变
* 量的地方,相当于直接访问的这个常量,不需要在运行时确定。因此在上面的一段代码中,由于变量b
* 被final修饰,因此会被当做编译器常量,所以在使用到b的地方会直接将变量b替换为它的值;
* 而对于变量 c 的访问却需要在运行时通过  链接来进行。不过要注意,只有在编译期间能确切知道final
* 变量值的情况下,编译器才会进行这样的优化.
* 补注:
* 而我们知道String类型实现常量池技术,(结合反射一博文) 比如String st1 ="hellojava";
* String st2 ="hellojava";这是"hellojava"会存在方法区内的常量池中,又因为常量池是共享的
* ,所以只会存储一份,符号 st1和st2会存贮在栈中,并且俩个符号会指向同一个地址(及“hellojava"在常量池中的地址);
* */
Integer aa = 10;
Integer bb = 5;
Integer cc = 5;
Integer dd = bb+cc;
System.out.println(aa==dd);//输出结果为true;
//Java的数学计算是在内存栈里操作的其实比较的是基本类型(10=5+5),他们的值相同,因此结果为True

}
//第五种情况
public void importMethod2(){
String a = "hello2";
final String b = getHello();
String c = "hello";
String d = b + 2;
String e = c + 2;
System.out.println((a == d));//flase
//因为对于变量  b 和 c 的访问却需要在运行时通过  链接来进行,编译器就不会进行上述优化
System.out.println((a == e));//flase;
}
public static String getHello() {
return "hello";
}
}
//final 参数
class FinalArgument{
void with(final FinalClass fc){
//fc = new FinalClass(); 这样是不对的,因为fc是final,
fc.noFinalField = 100;//其所指向的对象的内容是可以改的,虽然在才并不影响原来的值;
}
}

//final方法;
class PrivateMethod{

public void  show(){
System.out.println("privateMethod"+" :"+"show()");
}
private void f(){
System.out.println("privateMethod"+" :"+"f()");
}
}
class PrivateFinalMethod extends PrivateMethod{
private void f(){
System.out.println("privateFinalMethod"+" :"+"f()");
}
}
class PrivateFinalMethod2 extends PrivateFinalMethod{
public void f(){
System.out.println("privateFinalMethod"+" :"+"f()");
}
}

//主函数:
public class FinalModifierStudy {
public static void showFinalClass(){
FinalClass fc = new FinalClass();
//The final field FinalClass.finalField cannot be assigned
//fc.finalField = 44;

fc.noFinalField =22;
fc.show();
//输出结果:
//i was a default final method ,because the class name is modified by final keyword :22
}

public static void showFinalField(){
FinalField ff = new FinalField(40);
ff.importMethod1();
}

public static void showFinalMethod(){
PrivateFinalMethod2 pfm2 = new PrivateFinalMethod2();
pfm2.f();//就是调用PrivateFinalMethod2中的方法 其不是继承来的也不是覆盖了父类的;
//采用多态的形式会出错:
PrivateFinalMethod pfm = new PrivateFinalMethod2();
//pfm.f();就会出错 因为private f()就相当于隐藏在类中的代码,只不过形式和父类有点像
//其既不是继承来的也不是覆盖父类的;
}
public static void main(String[] args) {
//showFinalClass();
showFinalField();
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java static final