标签:来替 hash html size lan containe java 重新定义 区别
@
final关键宇可用于修饰类、方法和变量,被它修饰的类、方法和变量不可改变。
成员变量是随类初始化或对象初始化而初始化的 。
对于 final 修饰的成员变量而言,一旦有了初始值,就不能被重新赋值,如果既没有在定义成员变量时指定初始值,也没有在初始化块、构造器中为成员变量指定初始值,那么这些成员变量的值将一直是系统默认分配的0、‘\u000‘、false或 null ,这些成员变也就完全失去了存在的意义。 因此:
Java语法规定 final 修饰的成员变量必须由程序员显式地指定初始值。
归纳起来, final 修饰的类变量、实例变量能指定初始值的地方如下:
public class FinalVariableTest{
    //定义成员变量时指定默认值,合法
   final int a = 6;
   //下面变量将在构造器或初始化块中分配初始值
    final String str;
   final int c;
   final static double d ;
   //既没有指定默认值 ,又没有在初始化块、构造器中指定初始值
    //下面定义的 ch 实例变量是不合法的
    // final char ch;
    //初始化块 ,可对没有指定默认值的实例变量指定初始值
   //;在初始化块中为实例变囊指定初始值,合法
   str = "He110";
  //定义 a 实例变量时已经指定了默认值
  //不能为 a 重新赋值,因此下面赋值语句非法
   // a = 9;
   
   //静态初始化块,可对没有指定默认值的类变量指定初始值
   static{
       //在静态初始化块中为类变量指定初始值,合法
       d = 5 . 6;
    }
    
     //构造器,可对既没有指定默认值, 又没有在初始化块中
     //指定初始值的实例变量指定初始值
  public FinalVariableTest (){
     //如果在初始化块中已经对 str 指定了初始值
    //那么在构造器中不能对 final 变量重新赋值,下面赋值语句非法
    // str = "java";
    c = 5;
    }
    
   public void changeFinal( ){
     //普通方法不能为 final 修饰的成员变量赋值
     //d= 1. 2;
    //不能在普通方法中为 final 成员变量指定初始值
   // ch = ‘ a ‘;
   }
   
publ i c static void main(String[] args){
    FinalVariableTest ft = new FinalVariableTest();
    System.out . println(ft . a);
    System . out.println(ft.c) ;
    System . out.println(ft.d);
    }
}
系统不会对局部变量进行初始化,局部变量必须由程序员显式初始化 。 因此:
使用 final 修饰局部变量时 , 既可以在定义时指定默认值,也可以不指定默认值 。
pub1ic c1ass Fina1Loca1Variab1eTest{
  pub1ic void test( final int a){
   // 不能对 fina1 修饰的形参赋值,下面语句非法
   // a = 5;
   }
   
 pub1ic static void main(String[] args){
   //定义 fina1 局部变量时指定默认值,则 str 变量无法重新赋值
   final String str = "hello";
   //下面赋值语句非法
   // str = " Java";
   // 定义 fina1 局部变量时没有指定默认值,则 d 变量可被赋值一 次
  final double d;
  // 第一次赋初始值,成功
  d = 5.6;
  // 对 fina1 变量重复赋值 , 下面语句非法
  // d = 3.4;
  }
  
}
c1ass Person{
   private int age;
   pub1ic Person() {
   }
  // 有参数的构造器
  pub1ic Person(int age){
   this.age = age;
   //省略 age 的 setter 和 getter 方法
   //age 的 setter 和 getter 方法
  }
}  
 
pub1ic c1ass Fina1ReferenceTest{
  pub1ic static void main(String[] args){
    //fina1 修饰数组变量, iArr 是一个引用变量
   fina1 int[] iArr = (5 , 6, 12, 9) ;
   System.out.print1n(Arrays.toString(iArr));
   //对数组元素进行排序,合法
   Arrays.sort(iArr);
   System.out.println(Arrays.toString(iArr));
  //对数组元素赋值,合法
  iArr[2] = - 8 ;
  System.out.println(Arrays.toString (iArr) );
  // 下面语句对 iArr 重新赋值,非法
  // iArr = null;
  // final 修饰 Person 变量 , p 是一个引用变量
  final Persoηp =new Person(45) ;
  // 改变 Person 对象的 age 实例变量 ,合法
  p.setAge(23) ;
  System.out.println(p.getAge()) ;
  //下面语句对 p 重新赋值 ,非法
 // p = null;
}
}
 
之所以要使用final 方法,可能是出于对两方面理由的考虑。
public class Test{
    public final void changeName(){
       // 方法体
    }
}
对于一个 private 方法 , 因为它仅在当前类中可见, 其子类无法访问该方法 , 所以子类无法重写该方法一一如果子类中定义一个与父类 private 方法有相同方法名、相同形参列表、相同返回值类型 的方法 ,也不是方法重写,只是重新定义了 一个新方法。因此, 即使使用 final 修饰一个 private 访问权限的方法,依然可 以在其子类中定义与该方法具有相同方法名 、 相同形参列表、相同返回值类型的方法。
public class PrivateFinalMethodTest{
  private final void test(){}
}  
class Sub extends PrivateFinalMethodTest{
  //下面的方法定义不会出现 问题
  public void test(){}
}
final 修饰的方法不能被重写 , 但是可以被重载 。
final 修饰的类不可被继承。
public final class Test {
   // 类体
}
不可变( immutable ) 类的意思是创建该类的实例后,该实例 的实例变量是不可改变的。 Java 提供的 8 个包装类和 java.lang.String 类都是不可变类 , 当创建它们的实例后 , 其实例的实例变量不可改变。
Double d = new Double(6.5) ;
String str =new String( "Hello");
如果需要创建自定义的不可变类,可遵守如下规则 。
定义一个不可变的 Address 类,程序把 Address 类的 detail 和 postCode 成员变量都使用 private隐藏起来,并使用 final 修饰这两个成员变量 , 不允许其他方法修改这两个成员变量的值。
public class Address{
   private final String detail ;
   private final String postCode ;
   // 在构造器里初始化两个实例变量
   public Address(){
    this .detail = "";
    this.postCode = "";
   }
   
  pub1ic Address(String detai1 , String postCode){
   this.deta = deta ;
   this.postCode = postCode ;
  }
   
  //仅为两个实例变量提供 getter 方法
  pub1ic String getDetai1(){
   return this.detai1 ;
  }
   
  pub1ic String getPostCode(){
   return this.postCode;
  }
   
  //重写 equa1s ()方法,判断两个对象是否相等
  pub1ic boo1ean equa1s(Object obj){
    if (this == obj ){
     return true ;
   }
   
   if(obj != nu11 && obj.getC1ass() == Address.c1ass{
    Address ad = (Address)obj;
    //当 detai1 和 postCode 相等时 , 可认为两个 Address 对象相等
    if(this . getDeta 工 1() .equa1s (ad . getDetai1())&& this.getPostCode (} . equa1s(ad.getPostCode())){
        return true ;
    }
   } 
  return fa1se ;
 } 
 
 pub1ic int hashCode(){
   return detai1.hashCode() + postCode.hashCode()*31;
 }
}  
参考:
【1】:《疯狂Java讲义》
【2】:https://www.runoob.com/java/java-modifier-types.html
【3】:《Java编程思想》
Java Review (十二、面向对象----final 修饰符)
标签:来替 hash html size lan containe java 重新定义 区别
原文地址:https://www.cnblogs.com/three-fighter/p/13052616.html