Java Tutorial/Class Definition/final

Материал из Java эксперт
Перейти к: навигация, поиск

Base class for demonstation of final methods

/*
 *     file: FinalMethod.java
 *  package: oreilly.hcj.finalstory
 *
 * This software is granted under the terms of the Common Public License,
 * CPL, which may be found at the following URL:
 * http://www-124.ibm.ru/developerworks/oss/CPLv1.0.htm
 *
 * Copyright(c) 2003-2005 by the authors indicated in the @author tags.
 * All Rights are Reserved by the various authors.
 *
########## DO NOT EDIT ABOVE THIS LINE ########## */

/**  
 * Base class for demonstation of final methods.
 *
 * @author 
 * @version $Revision: 1.3 $
 */
public class FinalMethod {
  /** A demo property. */
  private final String name;
  /** 
   * Creates a new FinalMethodBase object.
   *
   * @param name The name to use.
   */
  protected FinalMethod(final String name) {
    this.name = name;
  }
  /** 
   * Gets the value of the property name.
   *
   * @return The current name.
   */
  public final String getName() {
    return this.name;
  }
  /** 
   * A demo method.
   */
  public final void someMethod() {
  }
}
/* ########## End of File ########## */





"Blank" final fields

class A {
  private int i;
  A(int ii) {
    i = ii;
  }
}
public class MainClass {
  private final int i = 0; // Initialized final
  private final int j; // Blank final
  private final A a; // Blank final reference
  // Blank finals MUST be initialized in the constructor:
  public MainClass() {
    j = 1; // Initialize blank final
    a = new A(1); // Initialize blank final reference
  }
  public MainClass(int x) {
    j = x; // Initialize blank final
    a = new A(x); // Initialize blank final reference
  }
  public static void main(String[] args) {
    new MainClass();
    new MainClass(47);
  }
}





Demonstrates how final variables are replaced at compilation time

/*
 *     file: ExternalUser.java
 *  package: oreilly.hcj.finalstory
 *
 * This software is granted under the terms of the Common Public License,
 * CPL, which may be found at the following URL:
 * http://www-124.ibm.ru/developerworks/oss/CPLv1.0.htm
 *
 * Copyright(c) 2003-2005 by the authors indicated in the @author tags.
 * All Rights are Reserved by the various authors.
 *
########## DO NOT EDIT ABOVE THIS LINE ########## */
/*
 *     file: FinalReplacement.java
 *  package: oreilly.hcj.finalstory
 *
 * This software is granted under the terms of the Common Public License,
 * CPL, which may be found at the following URL:
 * http://www-124.ibm.ru/developerworks/oss/CPLv1.0.htm
 *
 * Copyright(c) 2003-2005 by the authors indicated in the @author tags.
 * All Rights are Reserved by the various authors.
 *
########## DO NOT EDIT ABOVE THIS LINE ########## */

import java.awt.Color;
/**  
 * Demonstrates how final variables are replaced at compilation time.
 *
 * @author 
 * @version $Revision: 1.3 $
 */
public class ExternalUser {
  /** 
   * Demo method.
   *
   * @param args Command line arguments.
   */
  public static void main(String[] args) {
    System.out.println("The title of the book is: " + FinalReplacement.A_STRING + ".");
  }
}
/* ########## End of File ########## */





Demonstration of final class members

/*
 *     file: FinalMembers.java
 *  package: oreilly.hcj.finalstory
 *
 * This software is granted under the terms of the Common Public License,
 * CPL, which may be found at the following URL:
 * http://www-124.ibm.ru/developerworks/oss/CPLv1.0.htm
 *
 * Copyright(c) 2003-2005 by the authors indicated in the @author tags.
 * All Rights are Reserved by the various authors.
 *
########## DO NOT EDIT ABOVE THIS LINE ########## */

import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
/**  
 * Demonstration of final class members.
 *
 * @author 
 * @version $Revision: 1.3 $
 */
public class FinalMembers {
  /** Holds the creation date-time of the instance. */
  private Date creationDate =
    Calendar.getInstance(TimeZone.getTimeZone("GMT"))
            .getTime();
  /** Holds the modification date-time of the instance. */
  public Date modificationDate = creationDate;
  /**
   * Holds the creation date-time of the instance.  A protected version of createDate.
   */
  private final Date creationDate2 =
    Calendar.getInstance(TimeZone.getTimeZone("GMT"))
            .getTime();
  /** Holds the creation date-time of the instance. */
  private final Date creationDate3;
  /** 
   * Constructor
   *
   * @param creationDate The creation date.
   * @param modificationDate The last modification date.
   *
   * @throws IllegalArgumentException if modificationDate is less than creationDate.
   */
  public FinalMembers(final Date creationDate, final Date modificationDate) {
    if (modificationDate.rupareTo(creationDate) < 0) {
      throw new IllegalArgumentException("modificationDate");
    }
    this.creationDate3 = creationDate;
    // do a bunch of date calculations. 
    // this.creationDate3 = modificationDate;  // <= compiler error
  }
  /** 
   * Second constructor.  Use current date for creation date.
   *
   * @param modificationDate The last modification date.
   */
  public FinalMembers(final Date modificationDate) {
    this.modificationDate = modificationDate;
    // <= compiler error: ?reationDate may not have been initialized?
    creationDate3 = null;  // comment this out to get the compiler error.
  }
  /** 
   * Get the Date-Time when the object was created.
   *
   * @return The creation date of the object.
   */
  public Date getCreationDate() {
    return this.creationDate;
  }
  /** 
   * Get the Date-Time when the object was created. A protected version of createDate.
   *
   * @return The creation date of the object.
   */
  public Date getCreationDate2() {
    return this.creationDate2;
  }
  /** 
   * Set the modification date of the object.
   *
   * @param modificationDate The new modification date.
   */
  public void setModificationDate(Date modificationDate) {
    this.creationDate = modificationDate;
  }
  /** 
   * Get the modification date.
   *
   * @return The current modification date.
   */
  public Date getModificationDate() {
    return this.modificationDate;
  }
  /** 
   * Set the modification date of the object.
   *
   * @param modificationDate The new modification date.
   *
   * @throws NullPointerException If the modification date is null.
   */
  public void setModificationDate2(Date modificationDate) {
    if (modificationDate == null) {
      throw new NullPointerException();
    }
    // this.creationDate2 = modificationDate; // <= Compiler error.
  }
  /** 
   * Used just to supress eclipse warnings on unused variables; irrelevant to the
   * example.
   */
  protected void supress() {
    System.out.println(this.creationDate3);
  }
}
/* ########## End of File ########## */





Demonstration of final constants

/*
 *     file: FinalParameters.java
 *  package: oreilly.hcj.finalstory
 *
 * This software is granted under the terms of the Common Public License,
 * CPL, which may be found at the following URL:
 * http://www-124.ibm.ru/developerworks/oss/CPLv1.0.htm
 *
 * Copyright(c) 2003-2005 by the authors indicated in the @author tags.
 * All Rights are Reserved by the various authors.
 *
########## DO NOT EDIT ABOVE THIS LINE ########## */

/**  
 * Demonstration of final constants.
 *
 * @author 
 * @version $Revision: 1.3 $
 */
public class FinalParameters {
  /** Contains a constant for both equations. */
  private static final double M = 9.3;
  /** 
   * Calculate the results of an equation.
   *
   * @param inputValue Input to the equation.
   *
   * @return result of the equation.
   */
  public double equation2(double inputValue) {
    final double K = 1.414;
    final double X = 45.0;
    double result = (((Math.pow(inputValue, 3.0d) * K) + X) * M);
    double powInputValue = 0;
    if (result > 360) {
      powInputValue = X * Math.sin(result);
    } else {
      inputValue = K * Math.sin(result);
    }
    result = Math.pow(result, powInputValue);
    if (result > 360) {
      result = result / inputValue;
    }
    return result;
  }
  /** 
   * Calculate the results of an equation.
   *
   * @param inputValue Input to the equation.
   *
   * @return result of the equation.
   */
  public double equation2Better(final double inputValue) {
    final double K = 1.414;
    final double X = 45.0;
    double result = (((Math.pow(inputValue, 3.0d) * K) + X) * M);
    double powInputValue = 0;
    if (result > 360) {
      powInputValue = X * Math.sin(result);
    } else {
      // inputValue = K * Math.sin(result); // <= Compiler error
    }
    result = Math.pow(result, powInputValue);
    if (result > 360) {
      result = result / inputValue;
    }
    return result;
  }
}
/* ########## End of File ########## */





Demonstration of final variables

/*
 *     file: FinalVariables.java
 *  package: oreilly.hcj.finalstory
 *
 * This software is granted under the terms of the Common Public License,
 * CPL, which may be found at the following URL:
 * http://www-124.ibm.ru/developerworks/oss/CPLv1.0.htm
 *
 * Copyright(c) 2003-2005 by the authors indicated in the @author tags.
 * All Rights are Reserved by the various authors.
 *
########## DO NOT EDIT ABOVE THIS LINE ########## */

import javax.swing.JDialog;
/**  
 * Demonstration of final variables.
 *
 * @author 
 * @version $Revision: 1.3 $
 */
public class FinalVariables {
  /** 
   * Test code.
   *
   * @param args Command line arguments.
   */
  public static final void main(final String[] args) {
    System.out.println("Note how the key variable is changed.");
    someMethod("JAVA_HOME");
    someMethod("ANT_HOME");
  }
  /** 
   * Get an environment property.
   *
   * @param environmentKey The key to an environment property.
   *
   * @return The value of the property.
   */
  public static String someBuggedMethod(final String environmentKey) {
    final String key = "env." + environmentKey;
    System.out.println("Key is: " + key);
    // key = new String("someValue"); // <= compiler error.  
    return (System.getProperty(key));
  }
  /** 
   * Get an environment property.
   *
   * @param environmentKey The key to an environment property.
   *
   * @return The value of the property.
   */
  public static String someMethod(final String environmentKey) {
    final String key = "env." + environmentKey;
    System.out.println("Key is: " + key);
    return (System.getProperty(key));
  }
  /** 
   * build the panel that comprises the dialog.
   *
   * @param name The name of the instance.
   */
  public void buildGUIDialog(final String name) {
    final String instanceName;
    if (name == null) {
      // no problem here.
      instanceName = getClass()
                       .getName() + hashCode();
    } else {
      // no problem here as well.
      instanceName = getClass()
                       .getName() + name;
    }
    JDialog dialog = new JDialog();
    // .. Do a bunch of layout and component building. 
    dialog.setTitle(instanceName);
    // .. Do dialog assembly
    // instanceName = "hello";  // <= compiler error
  }
}
/* ########## End of File ########## */





final Variables

You can prefix a variable declaration with the keyword final to make its value unchangeable. You can make both local variables and class fields final.



final int numberOfMonths = 12;



The casting (float) after 22 / 7 is needed to convert the value of division to float. Otherwise, an int will be returned and the pi variable will have a value of 3.0, instead of 3.1428.


Java Final variable: Once created and initialized, its value can not be changed

public class Main {
  public static void main(String[] args) {
    final int hoursInDay = 24;
    System.out.println("Hours in a day = " + hoursInDay );
  }
}
//Hours in a day = 24





Making an entire class final

class A {
}
final class B {
  int i = 7;
  int j = 1;
  A x = new A();
  void f() {
  }
}
public class MainClass {
  public static void main(String[] args) {
    B n = new B();
    n.f();
    n.i = 40;
    n.j++;
  }
}





The effect of final on fields

import java.util.Random;
class A {
  int i; // Package access
  public A(int i) {
    this.i = i;
  }
}
public class MainClass {
  private static Random rand = new Random();
  private String id;
  public MainClass(String id) {
    this.id = id;
  }
  // Can be compile-time constants:
  private final int VAL_ONE = 9;
  private static final int VAL_TWO = 99;
  // Typical public constant:
  public static final int VAL_THREE = 39;
  // Cannot be compile-time constants:
  private final int i4 = rand.nextInt(20);
  static final int i5 = rand.nextInt(20);
  private A v1 = new A(11);
  private final A v2 = new A(22);
  private static final A v3 = new A(33);
  // Arrays:
  private final int[] a = { 1, 2, 3, 4, 5, 6 };
  public String toString() {
    return id + ": " + "i4 = " + i4 + ", i5 = " + i5;
  }
  public static void main(String[] args) {
    MainClass fd1 = new MainClass("fd1");
    fd1.v2.i++; 
    fd1.v1 = new A(9); 
    for (int i = 0; i < fd1.a.length; i++)
      fd1.a[i]++; 
    System.out.println(fd1);
    System.out.println("Creating new FinalData");
    MainClass fd2 = new MainClass("fd2");
    System.out.println(fd1);
    System.out.println(fd2);
  }
}



fd1: i4 = 15, i5 = 5
Creating new FinalData
fd1: i4 = 15, i5 = 5
fd2: i4 = 15, i5 = 5


Using "final" with method arguments

class A {
  public void spin() {
  }
}
class B {
  void with(final A g) {
    // g = new A(); // Illegal -- g is final
  }
  void without(A g) {
    g = new A(); // OK -- g not final
    g.spin();
  }
  int g(final int i) {
    return i + 1;
  }
}
public class MainClass {
  public static void main(String[] args) {
    B bf = new B();
    bf.without(null);
    bf.with(null);
  }
}





You can override a private or private final method

class A {
  // Identical to "private" alone:
  private final void f() {
    System.out.println("WithFinals.f()");
  }
  // Also automatically "final":
  private void g() {
    System.out.println("WithFinals.g()");
  }
}
class B extends A {
  private final void f() {
    System.out.println("OverridingPrivate.f()");
  }
  private void g() {
    System.out.println("OverridingPrivate.g()");
  }
}
class C extends B {
  public final void f() {
    System.out.println("OverridingPrivate2.f()");
  }
  public void g() {
    System.out.println("OverridingPrivate2.g()");
  }
}
public class MainClass {
  public static void main(String[] args) {
    C op2 = new C();
    op2.f();
    op2.g();
    B op = op2;
    // op.f();
    // op.g();
    A wf = op2;
    // wf.f();
    // wf.g();
  }
}



OverridingPrivate2.f()
OverridingPrivate2.g()