Java中static、final、this、super的用法
一、static
静态变量
此类实例共享此静态变量,类装载时,只分配一块存储空间,所有此类的对象都可以操控此块存储空间。
(例如买了一瓶可乐,姐姐(对象1)喝了三分之一,弟弟(对象2)再拿起这瓶可乐时就只剩三分之二了)
public class StaticTest {
private static int staticInt =2; //私有静态属性staticInt
private int num = 2; //私有属性num
public StaticTest() { //叫StaticTest的方法
staticInt++; //自加
num++; //自加
System.out.println("staticInt = "+staticInt+" num = "+num); //打印输出语句
}
public static void main(String[] args) {
StaticTest test = newStaticTest(); //staticInt = 3;num = 3; //对象test
StaticTest test2 = new StaticTest(); //staticInt = 4;num = 3;静态变量会累加 //对象test2
}
}
静态方法
在一个类中定义一个方法为static,即:无需本类的对象即可调用此方法。(可直接调用)
class Simple{
static void Go(){
System.out.println("Go...");
}
}
public class Cal{
public static void main(String[] args){
Simple.go();
}
}
调用静态方法:“类名.方法名”,如上面的 Simple.go(); 。Java的类库中大量的静态方法正是为此定义的。
静态类
普通类不允许声明为静态,只有内部类才可以。
静态的内部类可以作为普通类使用,不需实例一个外部类。
如下代码所示:
class OuterCls{ //外部类
public static class InnerCls{ //静态内部类
InnerCls(){ //内部方法
System.out.println("InnerCls"); //内部方法体
}
}
}
public class StaticCls{ //测试类
public static void main(String[]args){ //主函数
OuterCls.InnerCls oi = new OuterCls.InnerCls(); //外部类.内部类 对象名 = new 外部类.内部类}
}
输出结果:InnerCls
二、 final
final成员
定义final变量时,一旦被初始化其值便不可改变。
初始化可以在两个地方:
一是在final定义时直接给其赋值。(在定义时给值)
二是在构造函数中给其赋值。(在函数中给值)
二选一对其赋值,不能双赋值
final方法
定义final方法,说明此方法已经满足要求了,不进行扩展了,可继承方法直接使用,但不可覆写方法。
另外有inline的机制,它可以调用final方法时,直接将方法主体插入到调用处,非例行方法调用。
例如:保存断点,压栈等
这样可能会使您的程序效率有所提高,但在大方法体内或 多处调用会使代码迅速膨胀,影响效率。
final类
final类无法继承,此类设计满足需求,不用修改或作后续扩展。
final类中的属性,可final可不final
Final类中的方法,因为类是final的关系,所以方法是final的。
(属性可final可不final,方法默认final)
下面的程序演示了final方法和final类的用法:
final class final{ //一个叫final的final类
final String str="final Data"; //final字符串str
public String str1="non final data"; //public字符串str1
final public void print(){ //final方法print()
System.out.println("final method."); //方法体
}
public void what(){ //public方法what()
System.out.println(str+"n"+str1); //方法体
}
}
public class FinalDemo{ //extends final无法继承
public static voidmain(String[] args){
final f = new final(); //对象f
f.what(); //f方法what()
f.print(); //f方法print()
}
}
三、this & super
在Java中,this通常指当前对象,super则指父类的。
当您想要引用当前对象的某个属性或方法时,您便可以使用this。
(this的另一个用途是调用当前对象的另一个构造函数)
当您想要引用 父 类 的某个属性或方法时,您便可以使用super。
在一般方法中:
父子类里属性或方法 有相同的名字,这时为了不至于混淆。
明确使用this指明某个属性或方法,使用this就是自己的,不使用就是父系的
下面的代码演示了上面的用法:
public class DemoThis{
private String name; //私有属性 name
private int age; //私有属性 age
public voidsetName(String name){
this.name=name; //此处必须指明您要引用成员变量
}
public void setAge(int age){
this.age=age;
}
public void print(){
System.out.println("Name="+name+"Age="+age);
//在此行中并不需要用this,没有混淆
}
DemoThis(String name,int age) {
setName(name); //这行可以加上this调用自己的方法
this.setName(name); //但这加上this并不是必须的
setAge(age); //加不加this效果都是一样的
this.print(); //因为本来就是在本类里
}
public static voidmain(String[] args){
DemoThis dt=newDemoThis("Kevin","22");
}
}
这段代码不用解释您也应该能看明白。
在构造函数中的this.print()
完全可以用print()来代替,效果是一样。
如下:
DemoThis(String name,int age) {
setName(name); //您可以加上this来调用方法
setAge(age); //效果是一样的
print(); //因为本来就是在类里
}
下面我们修改这个程序,来演示super的用法。
class Person{
public int c; //公共属性 c
private String name; //私有属性name
private int age; //私有属性age
protected void setName(String name){
this.name=name; //把新参数赋值给本name
}
protected void setAge(int age){
this.age=age; //把新参数赋值给本age
}
protected void print(){
System.out.println("Name="+name+" Age="+age);
}
}
public class DemoSuper(子) extends Person(父){
public void print(){ //自己的print()方法覆写父系print()方法
System.out.println("DemoSuper:"); //文本输出
super.print(); //调用父系的print()方法
}
public static void main(String[] args){
DemoSuper ds=new DemoSuper(); //实例化
ds.setName("kevin"); //setName
ds.setAge(22); //setAge
ds.print(); //print()
}
}
输出结果:
DemoSuper:
Name=kevin Age=22
DemoSuper子类中,新print方法覆写了父系print方法, 它先做自己的事情,然后调用父类print()方法。
总言之:this可访问自己的,super可访问父类的
在构造方法中:
构造方法是一种特殊的方法,在对象初始化的时候自动调用。在构造方法中,this和super也有上面说的种种使用方式,并且它还有特殊的地方,请看下面的例子:
class Person{
public static void prt(String s) //公共prt()方法
{ System.out.println(s); } //输出给定的字符串s
Person() //无参构造方法(父)
{ prt("A Person."); } //调用prt()方法
Person(String name) //有参构造方法(父)
{ prt("A person name is:"+name); } //调用prt()方法
}
public class Chinese(子) extends Person(父){
Chinese(){ //无参构造方法(子)
super(); //调用父类无参构造方法(灰色部分)
prt("A chinese."); //(4)调用prt()方法
}
Chinese(String name){ //有参构造方法(子)
super(name); //调用父类有参构造方法(绿色部分)
prt("his name is:"+name); //调用prt()方法
}
Chinese(Stringname,int age){ //有参构造方法(子)
this(name);//调用当前有参的构造方法(上一段)
prt("his age is:"+age);
}
public staticvoid main(String[] args){
Chinese cn=newChinese(); // 实例对象cn
cn=newChinese("kevin"); //cn name构造
cn=newChinese("kevin",22); //cn name+age构造
}
}
super后加参数是用来调用父类具有相同形式的构造函数
this 后加参数则用来调用当前具有相同参数的构造函数
上面涉及构造方法的重载,在Chinese的各个重载构造方法中,this和super在一般方法中的各种用法也仍可使用。
上面(4)可为“this.prt”(因为继承,所以自己也有prt方法)或者为“super.prt”(因为父类中有这方法且可被子类访问)。
但不管是this.prt()还是super.prt()都显得多此一举。
最后记住: “this通常指代当前对象,super通常指代父类”