|
home—info—exams—lectures—labs—hws
Recipe—Laws—lies—syntax—java.lang docs—java.util docs
java source, all files (source), all files (.jar).
Recall the first methods we wrote, which were part of class PizzaServer: the method pizzaArea, as well as methods like crustArea and wedPizzaArea. Those methods were a bit odd, because it didn't matter which PizzaServer was asked; they all gave the same answer. That is, the answer didn't depend on the PizzaServer's state. We could make a million PizzaServers, and they'd all ask the same thing. (In fact, we might want that question answered even before any PizzaServers are created.)
Actually, it is possible to write methods which aren't tied to a particular instance.
A static method is a method which is not called through an individual instance. Instead, it is associated only with a class (but no instances of that class). This means you can call that method even if an instance has never been created.Really, pizzaArea should have been a static method:
class PizzaServer { public double MINIMUM_WAGE = 5.15; private double salary = MINIMUM_WAGE; private double balance = 0; private String almaMater; // ...Constructors, setters omitted public static double pizzaArea( double diam ) { double radius = diam/2; return 3.14 * radius * radius ); } } |
Then, from the code pad, we can now write:
PizzaServer.pizzaArea(12) PizzaServer.pizzaArea(1) PizzaServer.pizzaArea(0) |
- To write a static method: include the adjective “static” in front of the signature.
- To call a static method: write “class-dot-methodName”, instead of “instance-dot-methodName”.
- When to make a method static: When its answer does not depend on which instance which you ask. Also, if it makes sense to call the method even if no instances have yet been created, then you'll need the method to be static.
Or, consider Math.sqrt. It's natural question to ask what the square root of some number is; but it's odd to say you must ask some particular Math object. I'd lied earlier; there is no Math object (we never called new, so there couldn't have been an object!). Instead, Math is just a class chock full of static methods.
Or, consider:
when writing Explorer methods, we really wish
we had a method createNewLint().
Clearly, such a method would belong in class Treasure.
But: it seems odd that you walk up to one Treasure (say, a chocolate egg)
and ask it to create a Lint for you.
Really, we want a method which we can call even if no (other) Treasures
have been created yet.
warning: The Java keyword “static” means “associated with the class, not a particular instance”. It does not mean “unchanging”.
You cannot mention this in a static method.This means you can't call (non-static) methods from inside a static method: you can't say this.getSalary(). (This further means that you can't even write getSalary, because
Note that you can certainly might have object-references that were passed in as arguments; you can certainly invoke methods on those parameters:
static Treasure theBetterOf( Treasure t1, Treasure t2 ) { if (t1.getWeight() < t2.getWeight()) { return t1; } else { return t2; } } |
Remember, the solution to the error message “cannot access method/field from a static context” is probably not making the method or field static. Although that gets rid of the error message, it's almost certainly not what you to do, if the enclosing method (“context”) really was meant to be static. The proper solution is to
We currently have tension between a law of programming, and a rule-of-thumb:
class PizzaServer() { /** The wage, in $/hr. */ private double salary; /** The minimum wage (in $/hr). */ public static double MINIMUM_WAGE = 5.15; /** Constructor. * @param The initial salary (in $/hr) */ PizzaServer( double _startSalary ) { if (_salary < MINIMUM_WAGE) { this.salary = MINIMUM_WAGE; } else { this.salary = _salary; } this.startSalary = _startSalary; } /** Set this PizzaServer's salary (subject to federal minimum wage). * @param _salary The new salary rate. * If _salary is below the min.wage ({@value MINIMUM_WAGE}), we use that instead. */ void setSalary( double _salary ) { if1 (_salary < MINIMUM_WAGE) { this.salary = MINIMUM_WAGE; } else { this.salary = _salary; } } } |
Thus we have an easy solution to the above tension: write static methods to do the work which you want to call from a constructor as well as other places:
/** Return the * @param The proposed salary. */ static double legalSalary( double _salary ) { if (_salary < MINIMUM_WAGE) { return MINIMUM_WAGE; } else { return _salary; } } /** Constructor. * @param The initial salary (in $/hr) */ PizzaServer( double _startSalary ) { this.startSalary = legalSalary( _startSalary ); } /** Set this PizzaServer's salary (subject to federal minimum wage). * @param _salary The new salary rate. * If _salary is below the MINIMUM_WAGE, we use that instead. */ void setSalary( double _salary ) { this.salary = legalSalary( _salary ); } |
1This if-statement could expressed more concisely
using Java's conditional operator:
home—info—exams—lectures—labs—hws
Recipe—Laws—lies—syntax—java.lang docs—java.util docs
©2007, Ian Barland, Radford University Last modified 2007.Aug.27 (Mon) |
Please mail any suggestions (incl. typos, broken links) to ibarlandradford.edu |