MiscLang - People.cs.uchicago.edu

Download Report

Transcript MiscLang - People.cs.uchicago.edu

Misc Language Features
Features that were added relatively
recently that are now in common use
Assertions
• Use the assert statement to insert assertions at
particular points in the code. The assert statement
can have one of two forms:
– assert booleanExpression;
– assert booleanExpression : errorMessage;
• The errorMessage is an optional string
message that would be shown when an
assertion fails.
Assertions
Example: Simple check for rogue values
Class Foo{
public void foo(int x[], int n){
assert n > 0 && n < x.length; “n out of range”;
…
}
}
Example: Simple check for null object
class Foo{
public void foo(){
Student s = StudentFactory.create(“Graduate”);
assert s != null;
}
}
Assertions
• Assertions are not typically used to signal errors in
production client application code.
• Rather, they are used
– During development
– By library writers to signals errors to library users (who
themselves are software developers!)
• java –ea | -da Program
– (“enable assertions” or “disable assertions”)
foreach loop
// Returns the sum of the elements of a
int sum(int[] a) {
int result = 0;
for (int i : a)
result += i;
return result;
}
//Compare to old way
int sum(int[] a) {
int result = 0;
for (int i = 0; i < a.length; ++i)
result += a[i];
return result;
}
Much cleaner syntax!
Think “for each i in the
Collection a”
foreach with 2D Arrays
for (int row = 0; row < a2.length; row++) {
for (int col = 0; col < a2[row].length; col++) {
output += " " + a2[row][col];
}
output += "\n”;
}
for (int[] row : a2){
for (int val: row){
output += " " + a2[row][col];
}
output += "\n”;
}
foreach with Collections
This ugly code
for (Iterator i = suits.iterator(); i.hasNext(); ) {
Suit suit = (Suit) i.next();
for (Iterator j = ranks.iterator(); j.hasNext(); )
sortedDeck.add(new Card(suit, j.next()));
}
Can be replaced by …
for (Suit suit : suits)
for (Rank rank : ranks)
sortedDeck.add(new Card(suit, rank));
Note however that the underlying Iterator is hidden, so only useful for moving
through data, cannot delete, move backwards, etc.
Varargs
• Asa of 1.5 Java allows you to define/call methods with variable
number of arguments.
• Before
– void foo(int i, String[] args) was called as
– String args[] = {“hello”, “goodbye”};
– foo(1, args);
• As of 1.5 it can also be called without the user having to create an
array
–
–
–
–
void foo(int i, String… args)
foo(1,”hello”, “goodbye”);
foo(1, “my”, “name”, “is”, “Andrew”);
foo(1, “this”, “argument”, “list”, “can”, “be”, “any”, length”);
This is not limited to Strings, any object and native types can be used as
well.
Varargs
• Note that the vararg parameter, denoted by the ellipses
(“…”), must always be the last one.
• Inside the method the … parameter is always handled as an
array of whatever size.
• However, it can be called as a method with any number of
arguments without having to box them in an array!
• This is really just a convenience, lying somewhere between
overloading and forcing the user to create an array.
public class VarargsTest
public static double average( double... numbers ){
double total = 0.0; // initialize total
// calculate total using the enhanced for statement
for ( double d : numbers )
total += d;
return total / numbers.length;
}
public static void main( String args[] ) {
double d1 = 10.0;
double d2 = 20.0;
double d3 = 30.0;
double d4 = 40.0;
System.out.printf( "d1 = %.1f\nd2 = %.1f\nd3 = %.1f\nd4 = %.1f\n\n",
d1, d2, d3, d4 );
System.out.printf( "Average of d1 and d2 is %.1f\n",
average( d1, d2 ) );
System.out.printf( "Average of d1, d2 and d3 is %.1f\n",
average( d1, d2, d3 ) );
System.out.printf( "Average of d1, d2, d3 and d4 is %.1f\n",
average( d1, d2, d3, d4 ) );
}
Static import
• In order to access static members, it is necessary to qualify
references with the class they came from. For example
– Math.cos(Math.PI * theta);
• Now, can avoid this with:
– import static java.lang.Math.PI;
– Import static java.lang.Math.* (to import all static members)
• Once the static members have been imported, they may be
used without qualification:
– double r = cos(PI * theta);
• Use sparingly!
Enumerated types
• A very useful technique to define integer types
that can only store specific values (enforced by
compiler) and can be referred to by useful names.
• Before enumerated types:
–
–
–
–
public static final int SEASON_WINTER = 0;
public static final int SEASON_SPRING = 1;
public static final int SEASON_SUMMER = 2;
public static final int SEASON_FALL = 3;
• New way:
– enum Season {WINTER, SPRING, SUMMER, FALL };
– Season.Winter has a value of 0, Seaon.SPRING has a value of 1, …
New way
• Season now declares a new type that can
only have the specified values!
– Enhanced compiler-time checking possible
– Also declares a namespace
– In old way printed values are uninformative
Because they are just ints, if you print one out
all you get is a number, which tells you nothing
about what it represents, or even what type it is.
enum Month{JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC};
enum Season{WINTER,SPRING,SUMMER,FALL};
public class EnumTest{
public static void main(String[] args){
Season season = Meteorology.getMeteorologicalSeason(Month.JAN);
System.out.println(season);
}
}
class Meteorology{
public static Season getMeteorologicalSeason(Month month){
//NOTE: unqualified name required in switch statement!
switch(month){
case JAN:
return Season.WINTER;
case FEB:
return Season.WINTER;
//...
default:
return Season.SUMMER;
}
}
}
Enumerated Types, cont.
• All enum types extend
java.lang.enum
(and thus not java.lang.Object!)
• Like classes enum types can be either public or
default (package) scope
• Note that we can also set the internal integer values
to anything we choose
enum Season{Winter=3,SPRING=4, …}
More than meets the eye
• What has been discussed so far are the basics and
include most of what is expected from enumerated
types in other languages.
• However, in JavaEnumerated types also have many
other cool high-level features that make them better
than C enums
–
–
–
–
–
–
They can have fields and constructors
They can have methods
They can be looped over as collections
They can be looped over in ranges
They can be cloned
They can be printed
• See Enum.java in class examples
Adding methods to enum types
public enum Season{
SUMMER, SPRING, FALL, WINTER;
public String clothing(){
if (this == SUMMER)
return("short sleeves");
else if (this == SPRING)
return("Winter coat");
else if (this == FALL)
return("long sleeves");
else if (this == WINTER)
return("two winter coats");
return(null);
}
}
Note that enums
Can be declared
In their own classesscc
For enums, “this” refers
to the value of the operating
Enumerated type (ie SUMMER,
SPRING, etc.)
Enum properties, cont.
• enum types inheret a toString method that will give the
String representation of the value of the elements
> Season s = Season.WINTER;
> String sval = s.toString();
> System.out.pritnln(sval)
> WINTER
Or just
> System.out.println(s);
• enum types can be looped over as collections using the values
method inherited from Enum
– for (Season s : Season.values())
System.out.println(s);
• No reason not to take this a step further and allow enumerated tyes
to behave more like regular classes with fields, methods, constructors,
etc. In fact this is possible (if not so common)
enum Planet{
MERCURY (3.303e+23, 2.4397e6),
VENUS (4.869e+24, 6.0518e6),
EARTH (5.976e+24, 6.37814e6),
MARS (6.421e+23, 3.3972e6),
JUPITER (1.9e+27, 7.1492e7),
SATURN (5.688e+26, 6.0268e7),
URANUS (8.686e+25, 2.5559e7),
NEPTUNE (1.024e+26, 2.4746e7);
private final double mass; // in kilograms
private final double radius; // in meters
These invoke constructor
Semicolon required before fields/methods
Note that you cannot call
the constructor in the regular
way. It is private or package
scope and is called internally
Planet(double mass, double radius) { this.mass = mass; this.radius = radius; }
private double mass() { return mass; }
private double radius() { return radius; } // universal gravitational constant (m3 kg-1 s-2)
public static final double G = 6.67300E-11;
public double surfaceGravity() {
return G * mass / (radius * radius); }
public double surfaceWeight(double otherMass)
{ return otherMass * surfaceGravity(); }
C-style printing: printf method
In 1.5 If C-style printing was added as a method on the PrintStream class:
import java.io.*;
public class PrintTest{
public static void main(String[] args){
float x = 1.2f;
PrintStream p = new PrintStream(System.out);
p.printf("%s: %f\n", "the result is", x);
}
}
Format statements can be very sophisticated.