220 likes | 463 Views
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;
E N D
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 Note that enums Can be declared In their own classesscc 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); } } 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 • 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(); } 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
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.