Java 关键字 static 和final 理解
2017-03-31 14:48
465 查看
Static :
static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,
被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就为static变量分配一块固定的内存地址。因此运行时可以直接指向这块固定的内存地址而无需实例化。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。
1. 静态变量:
静态变量会在类被加载时初始化且只会被初始化一次。代表不论由哪个句柄指向的堆的内存地址只有一个。所有可以由类.变量名直接引用。该类所有实例的这个变量都指向同一个地址,因此称为静态变量。
2. 静态方法:
静态方法可以直接通过类名调用,任何的实例也都可以调用,
因为静态方法代表对所有实例均一致的特性。因此静态方法中不能设计特定实例的个性。所以不能用this和super关键字,不能直接访问所属类的实例变量和实例方法(就是不带static的成员变量和成员方法),只能访问所属类的静态成员变量和成员方法。
3. 静态代码块:
独立于类成员的代码块,用static修饰。只在jvm加载类时执行一次。
扩展:单例模式的使用。
public class SingletonStudentHungry {
// 静态成员变量先初始化,且只初始化一次。因此类调用的静态变量都存在同一个内存空间。
private static SingletonStudentHungry ssh = new SingletonStudentHungry();
private String name;
private SingletonStudentHungry() {
}
public void setName(String name) {
this.name = name;
}
public static synchronized SingletonStudentHungry getSingletonStudentHungry(String name) {
ssh.setName(name);
return ssh;
}
public void printSs() {
System.out.println(this);
}
@Override
public String toString() {
return "SingletonStudent [name=" + name + "]" + "\nhashcode:" + this.hashCode();
}
public static void main(String[] args) {
SingletonStudentHungry s1 = getSingletonStudentHungry("n1");
s1.printSs();
SingletonStudentHungry s2 = getSingletonStudentHungry("n2");
// 由于指向同一个堆内存地址,因此更改响应值后,所有指向哪个内存的句柄获取的name值均改变
s1.printSs();
s2.printSs();
}
}运行结果:
Final:
1. final类:
final类不能被继承,因此final类的成员方法没有机会被覆盖,默认都是final的。在设计类时候,如果这个类不需要有子类,类的实现细节不允许改变,并且确信这个类不会载被扩展,那么就设计为final类。
2. final方法:
如果一个类不允许其子类覆盖某个方法,则可以把这个方法声明为final方法。
使用final方法的原因有二:
第一、把方法锁定,防止任何继承类修改它的意义和实现。
第二、高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。
3. final变量:
对于基础数据类型:用final定义后,如 final int a = 10;会为a在栈空间分配值,值为10.而final定义则是句柄指向的位置不能更改。因此不能对a的值进行更改。
对于引用数据类型,即类,接口,数组。定义后,栈内存储堆的内存位置。而使用final定义后,句柄始终指向那个堆,堆内存储数据可以更改,但是句柄到堆内存的指向不能更改。
4. final 参数
当函数参数为final类型时,你可以读取使用该参数,但是无法改变该参数的值。
输出结果:
参考文章:内存管理 http://liu1227787871.blog.163.com/blog/static/205363197201263103320466/
static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,
被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就为static变量分配一块固定的内存地址。因此运行时可以直接指向这块固定的内存地址而无需实例化。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。
1. 静态变量:
静态变量会在类被加载时初始化且只会被初始化一次。代表不论由哪个句柄指向的堆的内存地址只有一个。所有可以由类.变量名直接引用。该类所有实例的这个变量都指向同一个地址,因此称为静态变量。
2. 静态方法:
静态方法可以直接通过类名调用,任何的实例也都可以调用,
因为静态方法代表对所有实例均一致的特性。因此静态方法中不能设计特定实例的个性。所以不能用this和super关键字,不能直接访问所属类的实例变量和实例方法(就是不带static的成员变量和成员方法),只能访问所属类的静态成员变量和成员方法。
3. 静态代码块:
独立于类成员的代码块,用static修饰。只在jvm加载类时执行一次。
扩展:单例模式的使用。
public class SingletonStudentHungry {
// 静态成员变量先初始化,且只初始化一次。因此类调用的静态变量都存在同一个内存空间。
private static SingletonStudentHungry ssh = new SingletonStudentHungry();
private String name;
private SingletonStudentHungry() {
}
public void setName(String name) {
this.name = name;
}
public static synchronized SingletonStudentHungry getSingletonStudentHungry(String name) {
ssh.setName(name);
return ssh;
}
public void printSs() {
System.out.println(this);
}
@Override
public String toString() {
return "SingletonStudent [name=" + name + "]" + "\nhashcode:" + this.hashCode();
}
public static void main(String[] args) {
SingletonStudentHungry s1 = getSingletonStudentHungry("n1");
s1.printSs();
SingletonStudentHungry s2 = getSingletonStudentHungry("n2");
// 由于指向同一个堆内存地址,因此更改响应值后,所有指向哪个内存的句柄获取的name值均改变
s1.printSs();
s2.printSs();
}
}运行结果:
Final:
1. final类:
final类不能被继承,因此final类的成员方法没有机会被覆盖,默认都是final的。在设计类时候,如果这个类不需要有子类,类的实现细节不允许改变,并且确信这个类不会载被扩展,那么就设计为final类。
2. final方法:
如果一个类不允许其子类覆盖某个方法,则可以把这个方法声明为final方法。
使用final方法的原因有二:
第一、把方法锁定,防止任何继承类修改它的意义和实现。
第二、高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。
3. final变量:
对于基础数据类型:用final定义后,如 final int a = 10;会为a在栈空间分配值,值为10.而final定义则是句柄指向的位置不能更改。因此不能对a的值进行更改。
对于引用数据类型,即类,接口,数组。定义后,栈内存储堆的内存位置。而使用final定义后,句柄始终指向那个堆,堆内存储数据可以更改,但是句柄到堆内存的指向不能更改。
4. final 参数
当函数参数为final类型时,你可以读取使用该参数,但是无法改变该参数的值。
public class Student { private String name; public Student(){} public Student(String name) { this.name = name; } public void setName(String name) { this.name = name; } public void printStudent(){ System.out.println(this); } public void changeName(Student s1 , String newName){ s1.setName(newName); } public void cannotChangeName(Student s2, String newName){ s2 = new Student(newName);//由于声明的s2指向另一块内存地址,因此对传入的参数没有影响 } @Override public String toString() { return "Student [name=" + name + "]"+"\n " + "hashcode:"+this.hashCode(); } }
public class FinalTest { private final int a = 10; private final Student student = new Student("caiwuxin"+":"+Math.random()); public FinalTest(){ } public static void main(String []args){ FinalTest f1 = new FinalTest(); f1.student.printStudent(); f1.student.changeName(f1.student, "newName"); f1.student.printStudent(); f1.student.cannotChangeName(f1.student, "annotherName"); f1.student.printStudent(); System.out.println("----------------------------------"); FinalTest f2 = new FinalTest(); f2.student.printStudent(); f2.student.changeName(f2.student, "newName"); f2.student.printStudent(); f2.student.cannotChangeName(f2.student, "annotherName"); f2.student.printStudent(); //a++;无法更改 } }
输出结果:
参考文章:内存管理 http://liu1227787871.blog.163.com/blog/static/205363197201263103320466/
相关文章推荐
- 浅析对Java关键字final和static的理解
- 【Java基础】java中常用关键字理解this、static、final、volatile理解
- 理解Java中的final和static关键字
- 对Java关键字final和static的理解
- java夯实基础系列:深入理解static、final关键字
- 对Java关键字final和static的理解
- Java中关键字static,final的理解
- Java关键字final、static使用总结
- java 编程思想笔记之static 和 final 关键字
- Java关键字final、static使用总结
- java 关键字final 和 static
- Java关键字final、static使用总结
- Java关键字final、static使用总结关键字
- java static和final的理解
- Java关键字final、static使用总结
- Java关键字final、static使用总结
- Java关键字final、static使用总结
- Java关键字final、static使用总结
- java 关键字final 和 static
- Java关键字final、static使用总结