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对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树