Java Tutorial Excelente Importante
Java Tutorial Excelente Importante
1. /* 2. Java Interface example. 3. This Java Interface example describes how interface is defined and 4. being used in Java language. 5. 6. Syntax of defining java interface is, 7. <modifier> interface <interface-name>{ 8. //members and methods() 9. } 10. */ 11. 12. //declare an interface 13. interface IntExample{ 14. 15. /* 16. Syntax to declare method in java interface is, 17. <modifier> <return-type> methodName(<optional-parameters>); 18. IMPORTANT : Methods declared in the interface are implicitly public and abstract. 19. */ 20. 21. public void sayHello(); 22. } 23. } 24. /* 25. Classes are extended while interfaces are implemented. 26. To implement an interface use implements keyword. 27. IMPORTANT : A class can extend only one other class, while it 28. can implement n number of interfaces. 29. */ 30. 31. public class JavaInterfaceExample implements IntExample{ 32. /* 33. We have to define the method declared in implemented interface, 34. or else we have to declare the implementing class as abstract class. 35. */ 36. 37. public void sayHello(){ 38. System.out.println("Hello Visitor !"); 39. } 40. 41. public static void main(String args[]){ 42. //create object of the class 43. JavaInterfaceExample javaInterfaceExample = new JavaInterfaceExample(); 44. //invoke sayHello(), declared in IntExample interface. 45. javaInterfaceExample.sayHello(); 46. } 47. } 48. 49. /* 50. OUTPUT of the above given Java Interface example would be : 51. Hello Visitor !
52. /* 53. Calculate Circle Area using Java Example 54. This Calculate Circle Area using Java Example shows how to calculate 55. area of circle using it's radius. 56. */ 57. 58. import java.io.BufferedReader; 59. import java.io.IOException; 60. import java.io.InputStreamReader; 61. 62. public class CalculateCircleAreaExample { 63. 64. public static void main(String[] args) { 65. 66. int radius = 0; 67. System.out.println("Please enter radius of a circle"); 68. 69. try 70. { 71. //get the radius from console 72. BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 73. radius = Integer.parseInt(br.readLine()); 74. } 75. //if invalid value was entered 76. catch(NumberFormatException ne) 77. { 78. System.out.println("Invalid radius value" + ne); 79. System.exit(0); 80. } 81. catch(IOException ioe) 82. { 83. System.out.println("IO Error :" + ioe); 84. System.exit(0); 85. } 86. 87. /* 88. * Area of a circle is 89. * pi * r * r 90. * where r is a radius of a circle. 91. */ 92. 93. //NOTE : use Math.PI constant to get value of pi 94. double area = Math.PI * radius * radius; 95. 96. System.out.println("Area of a circle is " + area); 97. } 98. } 99. 100. /* 101. Output of Calculate Circle Area using Java Example would be 102. Please enter radius of a circle 103. 19 104. Area of a circle is 1134.1149479459152
105. /* 106. Calculate Circle Perimeter using Java Example 107. This Calculate Circle Perimeter using Java Example shows how to calculate 108. Perimeter of circle using it's radius. 109. */ 110. 111. import java.io.BufferedReader; 112. import java.io.IOException; 113. import java.io.InputStreamReader; 114. 115. public class CalculateCirclePerimeterExample { 116. 117. public static void main(String[] args) { 118. 119. int radius = 0; 120. System.out.println("Please enter radius of a circle"); 121. 122. try 123. { 124. //get the radius from console 125. BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 126. radius = Integer.parseInt(br.readLine()); 127. } 128. //if invalid value was entered 129. catch(NumberFormatException ne) 130. { 131. System.out.println("Invalid radius value" + ne); 132. System.exit(0); 133. } 134. catch(IOException ioe) 135. { 136. System.out.println("IO Error :" + ioe); 137. System.exit(0); 138. } 139. 140. /* 141. * Perimeter of a circle is 142. * 2 * pi * r 143. * where r is a radius of a circle. 144. */ 145. 146. //NOTE : use Math.PI constant to get value of pi 147. double perimeter = 2 * Math.PI * radius; 148. 149. System.out.println("Perimeter of a circle is " + perimeter); 150. } 151. } 152. 153. /* 154. Output of Calculate Circle Perimeter using Java Example would be 155. Please enter radius of a circle 156. 19
157. Perimeter of a circle is 119.38052083641213 158. */ 159. /* 160. Calculate Rectangle Area using Java Example 161. This Calculate Rectangle Area using Java Example shows how to calculate 162. area of Rectangle using it's length and width. 163. */ 164. 165. import java.io.BufferedReader; 166. import java.io.IOException; 167. import java.io.InputStreamReader; 168. 169. public class CalculateRectArea { 170. 171. public static void main(String[] args) { 172. 173. int width = 0; 174. int length = 0; 175. 176. try 177. { 178. //read the length from console 179. BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 180. 181. System.out.println("Please enter length of a rectangle"); 182. length = Integer.parseInt(br.readLine()); 183. 184. //read the width from console 185. System.out.println("Please enter width of a rectangle"); 186. width = Integer.parseInt(br.readLine()); 187. 188. 189. } 190. //if invalid value was entered 191. catch(NumberFormatException ne) 192. { 193. System.out.println("Invalid value" + ne); 194. System.exit(0); 195. } 196. catch(IOException ioe) 197. { 198. System.out.println("IO Error :" + ioe); 199. System.exit(0); 200. } 201. 202. /* 203. * Area of a rectangle is 204. * length * width 205. */ 206. 207. int area = length * width; 208.
209. System.out.println("Area of a rectangle is " + area); 210. } 211. 212. } 213. 214. /* 215. Output of Calculate Rectangle Area using Java Example would be 216. Please enter length of a rectangle 217. 10 218. Please enter width of a rectangle 219. 15 220. Area of a rectangle is 150 221. */ 222. /* 223. Find Largest and Smallest Number in an Array Example 224. This Java Example shows how to find largest and smallest number in an 225. array. 226. */ 227. public class FindLargestSmallestNumber { 228. 229. public static void main(String[] args) { 230. 231. //array of 10 numbers 232. int numbers[] = new int[]{32,43,53,54,32,65,63,98,43,23}; 233. 234. //assign first element of an array to largest and smallest 235. int smallest = numbers[0]; 236. int largetst = numbers[0]; 237. 238. for(int i=1; i< numbers.length; i++) 239. { 240. if(numbers[i] > largetst) 241. largetst = numbers[i]; 242. else if (numbers[i] < smallest) 243. smallest = numbers[i]; 244. 245. } 246. 247. System.out.println("Largest Number is : " + largetst); 248. System.out.println("Smallest Number is : " + smallest); 249. } 250. } 251. 252. /* 253. Output of this program would be 254. Largest Number is : 98 255. Smallest Number is : 23 256. */
1. /* 2. Java Factorial Example 3. This Java Factorial Example shows how to calculate factorial of 4. a given number using Java. 5. */ 6. 7. public class NumberFactorial { 8. 9. public static void main(String[] args) { 10. 11. int number = 5; 12. 13. /* 14. * Factorial of any number is !n. 15. * For example, factorial of 4 is 4*3*2*1. 16. */ 17. 18. int factorial = number; 19. 20. for(int i =(number - 1); i > 1; i--) 21. { 22. factorial = factorial * i; 23. } 24. 25. System.out.println("Factorial of a number is " + factorial); 26. } 27. } 28. 29. /* 30. Output of the Factorial program would be 31. Factorial of a number is 120 32. */ 33. /* 34. Swap Numbers Java Example 35. This Swap Numbers Java Example shows how to 36. swap value of two numbers using java. 37. */ 38. 39. public class SwapElementsExample { 40. 41. public static void main(String[] args) { 42. 43. int num1 = 10; 44. int num2 = 20; 45. 46. System.out.println("Before Swapping"); 47. System.out.println("Value of num1 is :" + num1); 48. System.out.println("Value of num2 is :" +num2); 49. 50. //swap the value 51. swap(num1, num2); 52. } 53. 54. private static void swap(int num1, int num2) { 55. 56. int temp = num1;
57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79.
num1 = num2; num2 = temp; System.out.println("After Swapping"); System.out.println("Value of num1 is :" + num1); System.out.println("Value of num2 is :" +num2); } }
/* Output of Swap Numbers example would be Before Swapping Value of num1 is :10 Value of num2 is :20 After Swapping Value of num1 is :20 Value of num2 is :10 */ /* Swap Numbers Without Using Third Variable Java Example This Swap Numbers Java Example shows how to swap value of two numbers without using third variable using java. 80. */ 81. 82. public class SwapElementsWithoutThirdVariableExample { 83. 84. public static void main(String[] args) { 85. 86. int num1 = 10; 87. int num2 = 20; 88. 89. System.out.println("Before Swapping"); 90. System.out.println("Value of num1 is :" + num1); 91. System.out.println("Value of num2 is :" +num2); 92. 93. //add both the numbers and assign it to first 94. num1 = num1 + num2; 95. num2 = num1 - num2; 96. num1 = num1 - num2; 97. 98. System.out.println("Before Swapping"); 99. System.out.println("Value of num1 is :" + num1); 100. System.out.println("Value of num2 is :" +num2); 101. } 102. 103. 104. } 105. 106. /* 107. Output of Swap Numbers Without Using Third Variable example would be 108. Before Swapping 109. Value of num1 is :10 110. Value of num2 is :20 111. Before Swapping
Interfaz (Java)
interfaz en Lenguaje de programacin de Java es tipo abstracto cul se utiliza para especificar interfaz (en el sentido genrico del trmino) eso clases debe poner en ejecucin. Los interfaces son el usar declarado interfaz palabra clave, y puede contener solamente mtodo firmas y declaraciones constantes (declaraciones variables se declaran ser que esttico y final). Un interfaz puede nunca contener definiciones del mtodo. Como los interfaces estn implcito extracto, no pueden estar directamente instantiated. Las referencias del objeto en Java se pueden especificar para estar de un tipo del interfaz; en este caso deben cualquiera ser falta de informacin, o est limitado a un objeto que instrumentos el interfaz. La palabra clave instrumentos se utiliza declarar que una clase dada pone un interfaz en ejecucin. Una clase que pone un interfaz en ejecucin debe poner todos los mtodos en ejecucin en el interfaz, o sea clase abstracta. Una ventaja de usar interfaces es que simulan herencia mltiple. Todas las clases en Java (con excepcin de java.lang. Objeto, clase de la raz de la Java mecanografe el sistema) debe tener exactamente uno clase baja; herencia mltiple de clases no se permite. Sin embargo, una clase de Java/un interfaz puede poner en ejecucin/ampla cualquier nmero de interfaces.
Contenido
1 Interfaces 2 Uso o 2.1 Definir un interfaz o 2.2 Poner un interfaz en ejecucin o 2.3 Subinterfaces 3 Ejemplos 4 Modificantes del interfaz de Java 5 Referencias 6 Acoplamientos externos
Interfaces
Los interfaces se utilizan para codificar las semejanzas que las clases de los varios tipos parte, pero necesariamente no constituyen una relacin de la clase. Por ejemplo, a humano y a loro poder ambas silbe, no obstante no tendra sentido de representar Humanos y Loros
como subclases de a Whistler clasifique, ellos sera algo muy probablemente subclases del Animal clasifique (probablemente con las clases intermedias), pero ambo instrumento Whistler interfaz. Otro uso de interfaces est pudiendo utilizar objeto sin saber su tipo de clase, pero algo solamente de sa pone cierto interfaz en ejecucin. Por ejemplo, si uno fue molestado por un ruido que silbaba, uno puede no saber si es un ser humano o un loro, todo el que podra ser determinado es que un whistler est silbando. En un ejemplo ms prctico, a algoritmo que clasifica puede contar con un objeto del tipo Comparable. As, sabe que el tipo del objeto puede ser clasificado de alguna manera, pero es inaplicable cules el tipo del objeto es. La llamada whistler.whistle () llamar el mtodo puesto en ejecucin silbe del objeto whistler no importa qu la clase l tiene, con tal que ponga en ejecucin Whistler.
Uso
Definir un interfaz
Los interfaces se deben definir usando el frmula siguiente (compare a Definicin de la clase de Java).
[visibilidad] interfaz InterfaceName [extiende otros interfaces] { declaraciones constantes tipo declaraciones del miembro declaraciones abstractos del mtodo }
El cuerpo del interfaz contiene extracto mtodos, pero puesto que todos los mtodos en un interfaz son, por la definicin, extracto, extracto la palabra clave no se requiere. Puesto que el interfaz especifica un sistema de comportamientos expuestos, todos los mtodos estn implcito pblico. As, un interfaz simple puede ser
pblico interfaz Despredador { boleano chasePrey(Presa p); vaco eatPrey(Presa p); }
El tipo declaraciones del miembro en un interfaz es implcito esttico y pblico, pero de otra manera pueden ser cualquier tipo de clase o de interfaz.[1]
Si una clase pone un interfaz en ejecucin y no es extracto, y no pone todos sus mtodos en ejecucin, l debe ser marcado como extracto. Si una clase es abstracta, una de su subclases espera poner sus mtodos en ejecucin unimplemented. Las clases pueden poner interfaces en ejecucin mltiples
pblico clase Rana instrumentos Depredador, presa { ... }
Los interfaces son de uso general en la lengua de Java para servicios repetidos.[2] Java no permite pasar de los mtodos (procedimientos) como discusiones. Por lo tanto, la prctica es definir un interfaz y utilizarlo como la discusin y utilizar la firma del mtodo que sabe que la firma ser puesta en ejecucin ms adelante.
Subinterfaces
Los interfaces pueden extender varios otros interfaces, usando el mismo frmula se describen arriba. Por ejemplo
pblico interfaz VenomousPredator extiende Depredador, venenoso { cuerpo de //interface }
es legal y define un subinterface. Nota cmo permite herencia mltiple, desemejante de clases. Observe tambin eso Despredador y Venenoso puede definir o heredar posiblemente los mtodos con la misma firma, opinin matanza (presa de la presa). Cuando instrumentos de una clase VenomousPredator pondr ambos mtodos en ejecucin simultneamente.
Ejemplos
/* * En pocas antiguas, all * eran los monstruos y los Griegos * que se lucharon */
pblico extracto clase Criatura { protegido Secuencia nombre; //... pblico vaco ataque() { Sistema.hacia fuera.println(nombre + ataques!); } } pblico clase Achilles extiende Criatura { //... } pblico clase Mino extiende Criatura instrumentos Monstruo { //... pblico vaco rugido() { Sistema.hacia fuera.println(nombre + ruge en alta voz!); } } pblico interfaz Monstruo { vaco rugido(); } pblico esttico vaco principal(Secuencia[] args) { aCreature de la criatura; //... /el ** * usted tiene que echar aCreature para mecanografiar a monstruo porque * aCreature es un caso de la criatura, y no todo * las criaturas pueden rugir. Sabemos que es un monstruo, * por lo tanto puede rugir porque llegamos si * declaracin abajo. Ambas criaturas pueden atacar, as que nosotros * ataque cueste lo que cueste apenas si es un monstruo que * como a rugir antes de atacar. */ si(aCreature instanceof Monstruo) { M= del monstruo(Monstruo)aCreature; m.rugido(); monstruo as que nosotros de s. A. de //It el ' podemos rugir } //Both puede atacar aCreature.ataque(); }
tiene el mtodo compareTo, que se utiliza para describir dos objetos como igual, o indicar uno es el otro mayor que. Generics permita el poner de clases en ejecucin para especificar qu casos de la clase se pueden comparar a ellas. Serializable es a interfaz del marcador sin mtodos o campos - tiene un cuerpo vaco. Se utiliza para indicar que una clase puede ser serializado. Su Javadoc describe cmo debe funcionar, aunque no se hace cumplir nada programmatically.
pblico
extracto
privado
strictfp
protegido
Debe ser observado que el uso incorrecto de modificantes de interfaces puede dar lugar a comportamiento inestable del software.
import java.util.*; public class AClass { public int instanceInteger = 0; public int instanceMethod() { return instanceInteger; } public static int classInteger = 0; public static int classMethod() { return classInteger; } public static void main(String[] args) { AClass anInstance = new AClass(); AClass anotherInstance = new AClass(); //Refer to instance members through an instance. anInstance.instanceInteger = 1; anotherInstance.instanceInteger = 2; System.out.format("%s%n", anInstance.instanceMethod()); System.out.format("%s%n", anotherInstance.instanceMethod()); //Illegal to refer directly to instance members from a class method //System.out.format("%s%n", instanceMethod()); //System.out.format("%s%n", instanceInteger); //Refer to class members through the class... AClass.classInteger = 7; System.out.format("%s%n", classMethod()); //...or through an instance. System.out.format("%s%n", anInstance.classMethod()); //Instances share class variables anInstance.classInteger = 9; System.out.format("%s%n", anInstance.classMethod()); System.out.format("%s%n", anotherInstance.classMethod()); } } //illegal //illegal
package one; public class Alpha { //member variables private int privateVariable = 1; int packageVariable = 2; //default access protected int protectedVariable = 3; public int publicVariable = 4; //methods private void privateMethod() { System.out.format("privateMethod called%n"); } void packageMethod() { //default access System.out.format("packageMethod called%n"); } protected void protectedMethod() { System.out.format("protectedMethod called%n"); } public void publicMethod() { System.out.format("publicMethod called%n"); } public static void main(String[] args) { Alpha a = new Alpha(); a.privateMethod(); //legal a.packageMethod(); //legal a.protectedMethod(); //legal a.publicMethod(); //legal System.out.format("privateVariable: %2d%n", a.privateVariable); //legal System.out.format("packageVariable: %2d%n", a.packageVariable); //legal System.out.format("protectedVariable: %2d%n", a.protectedVariable); //legal System.out.format("publicVariable: %2d%n", a.publicVariable); //legal } }
package two; import one.*; public class AlphaTwo extends Alpha { public static void main(String[] args) { Alpha a = new Alpha(); //a.privateMethod(); //illegal //a.packageMethod(); //illegal //a.protectedMethod(); //illegal a.publicMethod(); //legal //System.out.format("privateVariable: // a.privateVariable); //illegal //System.out.format("packageVariable: // a.packageVariable); //illegal //System.out.format("protectedVariable: // a.protectedVariable); //illegal System.out.format("publicVariable: a.publicVariable); //legal %2d%n", %2d%n", %2d%n", %2d%n",
public enum MERCURY VENUS EARTH MARS JUPITER SATURN URANUS NEPTUNE
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; double surfaceGravity() { return G * mass / (radius * radius); } double surfaceWeight(double otherMass) { return otherMass * surfaceGravity(); } public static void main(String[] args) {
if (args.length != 1) { System.err.println("Usage: java Planet <earth_weight>"); System.exit(-1); } double earthWeight = Double.parseDouble(args[0]); double mass = earthWeight/EARTH.surfaceGravity(); for (Planet p : Planet.values()) System.out.printf("Your weight on %s is %f%n", p, p.surfaceWeight(mass)); } }
import java.util.*; public class Subclass extends Superclass { public boolean aVariable; //hides aVariable in Superclass public void aMethod() { //overrides aMethod in Superclass aVariable = false; super.aMethod(); System.out.format("%b%n", aVariable); System.out.format("%b%n", super.aVariable); } }
public class Superclass { public boolean aVariable; public void aMethod() { aVariable = true; } }
We can also implement the generic shapes class as an abstract class so that we can draw lines, circles, triangles etc. All shapes have some common fields and methods, but each can, of course, add more fields and methods. The abstract class guarantees that each shape will have the same set of basic properties. We declare this class abstract because there is no such thing as a generic shape. There can only be concrete shapes such as squares, circles, triangles etc.
public class Point extends Shape { static int x, y; public Point() { x = 0; y = 0; } public double area() { return 0; } public double perimeter() { return 0; } public static void print() { System.out.println("point: " + x + "," + y); } public static void main(String args[]) { Point p = new Point(); p.print(); } }
Output point: 0, 0 Notice that, in order to create a Point object, its class cannot be abstract. This means that all of the abstract methods of the Shape class must be implemented by the Point class. The subclass must define an implementation for every abstract method of the abstract superclass, or the subclass itself will also be abstract. Similarly other shape objects can be created using the generic Shape Abstract class. A big Disadvantage of using abstract classes is not able to use multiple inheritance. In the sense, when a class extends an abstract class, it cant extend any other class.
Java Interface
In Java, this multiple inheritance problem is solved with a powerful construct called interfaces. Interface can be used to define a generic template and then one or more abstract classes to define partial implementations of the interface. Interfaces just specify the method declaration (implicitly public and abstract) and can only contain fields (which are implicitly public static final). Interface definition begins with a keyword interface. An interface like that of an abstract class cannot be instantiated. Multiple Inheritance is allowed when extending interfaces i.e. one interface can extend none, one or more interfaces. Java does not support multiple inheritance, but it allows you to extend one class and implement many interfaces. If a class that implements an interface does not define all the methods of the interface, then it must be declared abstract and the method definitions must be provided by the subclass that extends the abstract class. Example 1: Below is an example of a Shape interface interface Shape { public double area(); public double volume(); } Below is a Point class that implements the Shape interface. public class Point implements Shape { static int x, y; public Point() { x = 0; y = 0; } public double area() { return 0; } public double volume() { return 0; } public static void print() { System.out.println("point: " + x + "," + y); } public static void main(String args[]) { Point p = new Point(); p.print();
} } Similarly, other shape objects can be created by interface programming by implementing generic Shape Interface. Example 2: Below is a java interfaces program showing the power of interface programming in java Listing below shows 2 interfaces and 4 classes one being an abstract class. Note: The method toString in class A1 is an overridden version of the method defined in the class named Object. The classes B1 and C1 satisfy the interface contract. But since the class D1 does not define all the methods of the implemented interface I2, the class D1 is declared abstract. Also, i1.methodI2() produces a compilation error as the method is not declared in I1 or any of its super interfaces if present. Hence a downcast of interface reference I1 solves the problem as shown in the program. The same problem applies to i1.methodA1(), which is again resolved by a downcast. When we invoke the toString() method which is a method of an Object, there does not seem to be any problem as every interface or class extends Object and any class can override the default toString() to suit your application needs. ((C1)o1).methodI1() compiles successfully, but produces a ClassCastException at runtime. This is because B1 does not have any relationship with C1 except they are siblings. You cant cast siblings into one another. When a given interface method is invoked on a given reference, the behavior that results will be appropriate to the class from which that particular object was instantiated. This is runtime polymorphism based on interfaces and overridden methods.
interface I1 { void methodI1(); // public static by default } interface I2 extends I1 { void methodI2(); // public static by default } class A1 { public String methodA1() { String strA1 = "I am in methodC1 of class A1"; return strA1; } public String toString() { return "toString() method of class A1";
} } class B1 extends A1 implements I2 { public void methodI1() { System.out.println("I am in methodI1 of class B1"); } public void methodI2() { System.out.println("I am in methodI2 of class B1"); } } class C1 implements I2 { public void methodI1() { System.out.println("I am in methodI1 of class C1"); } public void methodI2() { System.out.println("I am in methodI2 of class C1"); } } // Note that the class is declared as abstract as it does not // satisfy the interface contract abstract class D1 implements I2 { public void methodI1() { } // This class does not implement methodI2() hence declared abstract. } public class InterFaceEx { public static void main(String[] args) { I1 i1 = new B1(); i1.methodI1(); // OK as methodI1 is present in B1 // i1.methodI2(); Compilation error as methodI2 not present in I1 // Casting to convert the type of the reference from type I1 to type I2 ((I2) i1).methodI2(); I2 i2 = new B1(); i2.methodI1(); // OK i2.methodI2(); // OK // Does not Compile as methodA1() not present in interface reference I1 // String var = i1.methodA1(); // Hence I1 requires a cast to invoke methodA1 String var2 = ((A1) i1).methodA1(); System.out.println("var2 : " + var2); String var3 = ((B1) i1).methodA1(); System.out.println("var3 : " + var3); String var4 = i1.toString(); System.out.println("var4 : " + var4); String var5 = i2.toString(); System.out.println("var5 : " + var5); I1 i3 = new C1(); String var6 = i3.toString();
System.out.println("var6 : " + var6); // It prints the Object toString() method Object o1 = new B1(); // o1.methodI1(); does not compile as Object class does not define // methodI1() // To solve the probelm we need to downcast o1 reference. We can do it // in the following 4 ways ((I1) o1).methodI1(); // 1 ((I2) o1).methodI1(); // 2 ((B1) o1).methodI1(); // 3 /* * * B1 does not have any relationship with C1 except they are "siblings". * * Well, you can't cast siblings into one another. * */ // ((C1)o1).methodI1(); Produces a ClassCastException } }
Output I am in methodI1 of class B1 I am in methodI2 of class B1 I am in methodI1 of class B1 I am in methodI2 of class B1 var2 : I am in methodC1 of class A1 var3 : I am in methodC1 of class A1 var4 : toString() method of class A1 var5 : toString() method of class A1 var6 : C1@190d11 I am in methodI1 of class B1 I am in methodI1 of class B1 I am in methodI1 of class B1
implement the Recyclable interface, which could apply to many otherwise totally unrelated objects. Note: There is no difference between a fully abstract class (all methods declared as abstract and all fields are public static final) and an interface. Note: If the various objects are all of-a-kind, and share a common state and behavior, then tend towards a common base class. If all they share is a set of method signatures, then tend towards an interface. Similarities: Neither Abstract classes nor Interface can be instantiated. List of objects that implement this interface can be sorted automatically by sort method of the list interface. This interface has compareTo() method that is used by the sort() method of the list. In this code Employee class is implementing Comparable interface and have method compareTO(). ComparableDemo.java is showing the use of this interface. This class first makes a list of objects of type Employee and call sort method of java.util.Collections, which internally uses compareTo() method of Employee class and sort the list accordingly. Employee.java
public class Employee implements Comparable { int EmpID; String Ename; double Sal; static int i; public Employee() { EmpID = i++; Ename = "dont know"; Sal = 0.0; } public Employee(String ename, double sal) { EmpID = i++; Ename = ename; Sal = sal; } public String toString() { return "EmpID " + EmpID + "\n" + "Ename " + Ename + "\n" + "Sal" + Sal; } public int compareTo(Object o1) { if (this.Sal == ((Employee) o1).Sal)
return 0; else if ((this.Sal) > ((Employee) o1).Sal) return 1; else return -1; } }
ComparableDemo.java
import java.util.*; public class ComparableDemo{ public static void main(String[] args) { List ts1 = new ArrayList(); ts1.add(new Employee ("Tom",40000.00)); ts1.add(new Employee ("Harry",20000.00)); ts1.add(new Employee ("Maggie",50000.00)); ts1.add(new Employee ("Chris",70000.00)); Collections.sort(ts1); Iterator itr = ts1.iterator(); while(itr.hasNext()){ Object element = itr.next(); System.out.println(element + "\n"); } } }
Output:
EmpID 1 Ename Harry Sal20000.0 EmpID 0 Ename Tom Sal40000.0 EmpID 2 Ename Maggie Sal50000.0 EmpID 3 Ename Chris Sal70000.0
Java Introduction
In this lesson of the Java tutorial, you will learn... 1. About the Java Runtime Environment and how a Java program is created, compiled, and run 2. How to download, install, and set up the Java Development Kit Standard Edition 3. How to create a simple Java program
class names are listed with an initial uppercase letter. variable and function names are listed with an initial lowercase letter. the first letters of inner words are capitalized (e.g., maxValue).
terms you must use as is are listed in normal monospace type. terms that you must substitute for, either one of a set of allowable values, or a name of your own, or code, listed in italics. the following generic terms are used - you must substitute an appropriate term. Substitution Options An access word from: public, protected, private, or it can be omitted one or more terms that modify a declaration; these include the access terms as well as terms like: static, transient, or volatile A data type word; this can be a primitive, such as int, or the name of a class, such as Object; variants of this include: returnType and paramType
dataType
variableName The name of a variable; variants on this include paramName and functionName The name of a class; there will be variants of this used for different types of examples, such as: BaseClassName, DerivedClassName, InterfaceName, and ExceptionClassName
ClassName
Substitution Options
they occupy their own memory space. they are tracked as an individual process by the OS.
Traditional programs are compiled from source code into a machine and OS-specific binary executable file.
to run the program in different environments, the source code would be compiled for that specific target environment.
When you run a Java program, the OS is actually running the Java Runtime Engine, or JRE, as an executable program; it processes your compiled code through the Java Virtual Machine (usually referred to as the JVM). A Java source code file is compiled into a bytecode file.
you can consider bytecode as a sort of generic machine language. the compiled bytecode is read by the JVM as a data file. the JVM interprets the bytecode at runtime, performing a final mapping of bytecode to machine language for whatever platform it is running on. thus, Java programs are portable - they can be written in any environment, compiled in any environment, and run in any environment (as long as a JVM is available for that environment). the JVM manages its own memory area and allocates it to your program as necessary. although this involves more steps at runtime, Java is still very efficient, much more so than completely interpreted languages like JavaScript, since the time-consuming parsing of the source code is done in advance.
this could range from a plain text editor like Notepad, to a programmers' editor such as TextPad, EditPlus, or Crimson Editor, to a complex integrated development environment (IDE) like NetBeans, Eclipse, or JDeveloper the source code file should have a .java extension.
The javac compiler is then used to compile the source code into bytecode.
javac MyClass.java
the bytecode is stored in a file with an extension .class bytecode is universal - one bytecode file will run on any supported platform.
You then run the java runtime engine, which will then interpret the bytecode to execute the program.
java MyClass
the executable program you are running is: java. the class name tells the JVM what class to load and run the main method for. you must have a JVM made specifically for your hardware/OS platform.
look for the download of J2SE 1.6.0.10 (or the latest release version).
You can also download the API documentation and even the source code.
the documentation lists all the standard classes in the API, with their data fields and methods, as well as other information necessary to use the class you can view the docs online, but it is worth downloading it so that you don't have to be connected to the internet to use it
if you create an applet, this would run inside a web page in a browser.
After you have installed the JDK, you will need to set at least one environment variable in order to be able to compile and run Java programs. For more complex projects that pull together elements form different sources, you must set an additional environment variable or two.
a PATH environment variable enables the operating system to find the JDK executables when your working directory is not the JDK's binary directory CLASSPATH is Java's analog to PATH, the compiler and JVM use it to locate Java classes o often you will not need to set this, since the default setting is to use the JDK's library jar file and the current working directory o but, if you have additional Java classes located in another directory (a third-party library, perhaps), you will need to create a classpath that includes not only that library, but the current working directory as well (the current directory is represented as a dot) many IDE's and servers expect to find a JAVA_HOME environment variable o this would be the JDK directory (the one that contains bin and lib) o the PATH is then set from JAVA_HOME plus \bin o this makes it easy to upgrade your JDK, since there is only one entry you will need to change
The procedure to permanently set the environment variables varies slightly from one version of Windows to another; the following will work in many, including Windows XP. The process for Vista is similar, but slightly different:
1. 2. 3. 4. 5. 6. right-click on My Computer choose Properties select the Advanced tab click the Environment Variables button at the bottom check both the User and System variable lists to see if JAVA_HOME or PATH already exist if JAVA_HOME exists, check to see that it matches your most recent JDK (or the one you wish to use) 1. it is probably better to set this as a System variable 2. if it exists, click Edit, if not, click Add 3. for the variable name, enter JAVA_HOME 4. for the value, enter your JDK directory, such as Error. This text should not be shown. Please email [email protected] to report it: C:\Program Files\Java\jdk1.5.0_14 note that the space in the name can sometimes cause problems one solution is to put quote marks around the entry, as in " C:\Program Files\Java\jdk1.5.0_14 Error. This text should not be shown. Please email [email protected] to report it: C:\Program Files\Java\jdk1.5.0_14" an even better solution would be to use the 8-character form of the directory name, such as C:\Progra~1\Java\jdk1.5.0_14 Error. This text should not be shown. Please email [email protected] to report it: C:\Progra~1\Java\jdk1.5.0_14 (you can check if this works in your system by typing it into the address bar of a My Computer window)
7. for PATH, again select either Add or Edit o you could do this either as a User variable or a System variable o if there isn't already a JDK bin directory mentioned in the PATH, it will work as a User variable o if there is already a JDK mentioned, you would want to ensure that this new entry preceded the existing entry, so you would edit that variable o note that if the existing entry was created using JAVA_HOME, then we are already set correctly o if you "prepend" an entry to PATH , it will be found first, and therefore supercede any other directory - if you append to path, your directory won't be found if an earlier entry JDK entry exists (the following image shows a prepend) o also note that System variables precede User variables, so they will be found first
Setting environment variables from a command prompt If you set the variables from a command prompt, they will only hold for that session, but you could create a batch file that you could run each time you open a command prompt window. To set the PATH from a command prompt or batch file:
set PATH=C:\Progra~1\Java\jdk1.6.0_10\bin;%PATH%
early version s of the JDK required you to include the JDK's lib directory in the CLASSPATH; this is no longer necessary note that UNIX environments use $PATH and $CLASSPATH instead of %PATH% and %CLASSPATH%, and that the path element separator is a colon instead of a semicolon
The definition goes inside your class definition, and looks like:
public static void main(String[] args) { (code goes here) }
it must be public, because it will be called from outside your class (by the JVM). the static keyword defines an element (could be data or functional) that will exist regardless of whether an object of the class has been instantiated technically, even though you may run the class as a program, that doesn't mean that any object of that class is ever instantiated - you must instantiate one explicitly if you want to have one. the String[] args parameter list states that there will be an array of String objects given to the method - these are the command line arguments. to run the program, use the following from the command line:
java ClassName
for example, if we had an executable class called Hello, in a file called Hello.java that compiled to Hello.class, you could run it with:
java Hello
System.out.println()
In order to see something happen, we need to be able to print to the screen. There is a System class that is automatically available when your program runs (everything in it is static).
it contains, among other things, input and output streams that match stdin, stdout, and stderr (standard output, standard input, and standard error).
System.out is a static reference to the standard output stream. As an object, System.out contains a println(String) method that accepts a String object, and prints that text onto the screen, ending with a newline (linefeed).
there is also a print(String) method that does not place a newline at the end.
You can print a String directly, or you can build one from pieces.
it is worth noting that a String will automatically be created from a quote-delimited series of characters values can be appended to a String by using the + sign; if one item is a String or quotedelimited series of characters, then the rest can be any other type of data.
7. Save the file. 8. In a command prompt window, change to the directory where Hello.java is stored and type the following:
javac Hello.java
1. A prompt on the next line without any error messages indicates success. 9. Type:
java Hello
10. Press Enter. 1. You should see the message Hello World print in the window. Code Explanation
public class Hello
all Java code must be within a class definition. a class defines a type of object. a public class can be accessed by any other class. a public class must be in its own file, whose name is the name of the class, plus a dot and an file extension of java (e.g., Hello.java )
{ . . . }
curly braces denote a block of code (the code inside the braces). code within braces usually belongs to whatever immediately precedes them
public static void main(String[] args) {
words followed by parentheses denote a function. to be executable by itself, a class must have a function defined in this fashion; the name main means that execution will start with the first step of this function, and will end when the last step is done. it is public because it needs to be executed by other Java objects (the JVM itself is a running Java program, and it launches your program and calls its main function). it is static because it needs to exist even before one of these objects has been created. it does not return an answer when it is done; the absence of data is called void. the String[] args represents the additional data that might have been entered on the command line.
System.out.println("Hello World!");
System is an class within the JVM that represents system resources. it contains an object called out, which represents output to the screen (what many environments call standard out). note that an object's ownership of an element is denoted by using the name of the object, a dot, and then the name of the element. out in turn contains a function, println, that prints a line onto the screen (and appends a newline at the end). a function call is denoted by the function name followed by parentheses; any information inside the parentheses is used as input to the function (called arguments or parameters to the function). the argument passed to println() is the string of text "Hello World!". note that the statement ends in a semicolon (as all do Java statements).
Java Basics
In this lesson of the Java tutorial, you will learn... 1. 2. 3. 4. 5. 6. Understand Java's basic syntax rules, including statements, blocks, and comments Declare variables and construct statements using variables and literal (constant) values Become familiar with the primitive data types, as well as the String class. Understand many of Java's operators and the concept of operator precedence. Understand the rules that apply when data is converted from one type to another. Declare, write, and use simple methods
There are a limited number of reserved words that have a special meaning within Java.
you may not use these words for your own variables or methods examples: public, void, static, do, for, while, if
Most keyboard symbol characters (the set of characters other than alphabetic or numeric) have a special meaning Names may contain alphabetic characters, numeric characters, currency characters, and connecting characters such as the underscore ( _ ) character
names may not begin with a numeric character note that the set of legal characters draws from the entire Unicode character set also note that it is probably impossible to write a succinct set of rules about what are valid characters, other than to say a character, that when passed to Character.isJavaIdentifierPart(char ch), results in a true value
names (of classes, variables, and methods) command keywords single or compound symbols (compound symbols are when an operation is signified by a two-symbol combination) these entities are called tokens or symbols in computer science jargon
Tokens may be separated by spaces, tabs, carriage returns, or by use of an operator (such as +, -, etc.)
since names may not contain spaces, tabs, or carriage returns, or operator characters, these characters imply a separation of what came before them from what comes after them
once the compiler knows that two items are separate, it ignores any additional separating whitespace characters (spaces, tabs, or carriage returns)
Java Statements
A statement:
one step of code, which may take more than one line ends with a semicolon (the ; character) it is OK to have multiple statements on one line
from top to bottom (if more than one statement on a line, left to right)
Within a statement, execution of the individual pieces is not necessarily left to right
there are concepts called operator precedence and associativity that determine the order of operations within a statement
Blocks of Code
A block of code:
is enclosed in curly braces - start with { and end with } consists of zero, one, or more statements behaves like a single statement to the outside world a complete method is a block blocks may be nested - containing one or more blocks inside generally, blocks belong to whatever comes before them (although it is perfectly OK to create a block that does not, this is almost never done)
Example
If you want, go ahead and modify your Hello World program to match this example
Comments
A comment:
is additional non-executable text in a program, used to document code may also be used to temporarily disable a section of code (for debugging)
may span part of a line, for example, to temporarily disable part of a statement:
x = 3 /* + y */ ;
ends at the end of that line may be nested inside block comments
y = 7; /* * temporarily disable this line which has a comment to end of line x = 3 + y; // add 3 for some reason */
Java contains a self-documentation utility, javadoc, which builds documentation from comments within the code javadoc comments begin with /** and end with */ they only work as javadoc comments when placed at specific locations in your code (immediately above anything documentable - the class itself and its members), otherwise they are treated as ordinary comments
/** Represents a person, with a first nanme and last name. */ public class Person { /** The person's first name */ public String firstName; /** The person's last name */ public String lastName; }
Variables
Variables store data that your code can use There are two fundamental categories of variables, primitive data and references
with primitive data, the compiler names a memory location and uses to store the actual data - numeric values such as integers, floating point values, and the code values of single individual text characters are stored as primitives with references, the data is accessed indirectly - the compiler selects a memory location, associates it with the variable name, and stores in it a value that is effectively the memory address of the actual data - in Java, all objects and arrays are stored using references
Declaring Variables
Variables must be declared before they are used A declaration informs the compiler that you wish to:
create an identifier that will be accepted by the compiler within a section of code (exactly what that section is depends on how and where the variable is declared; that is the concept of scope, which will be addressed later) associate that identifier with a specified type of data, and enforce restrictions related to that in the remainder of your code create a memory location for the specified type of data associate the identifier with that memory location
Java uses many specific data types; each has different properties in terms of size required and handling by the compiler
the declaration specifies the name and datatype generally the declaration also defines the variable, meaning that it causes the compiler to allocate storage space in memory of the requested type's size a declaration may also assign in initial value (to initialize the variable) multiple variables of the same type can be declared in a comma-separated list
Effect
declares the name a to exist, and allocates a memory location to hold a 32bit integer same as above, and also assigns an initial value of 0
Note that different languages have different rules regarding trying to read data from variables that have not been initialized
some languages just let the value be whatever happened to be in that memory location already (from some previous operation) some languages initialize automatically to 0 some languages give a compiler or runtime error Java uses both of the last two: local variables within methods must be initialized before attempting to use their value, while variables that are fields within objects are automatically set to zero
Advanced Declarations
Local variables, fields, methods, and classes may be given additional modifiers; keywords that determine any special characteristics they may have
any modifiers must appear first in any declaration, but multiple modifiers may appear in any order Usage Comments
Keyword
for a variable, that means that the value cannot be changed for a method, the method cannot be overridden when extending the class a final field does not, however, have to be initialized immediately; the initial assignment may be done once during an object's construction
final
static
fields, only for fields and methods of objects methods, inner classes one copy of the element exists regardless of how many
Keyword
Usage
Comments
instances are created the element is created when the class is loaded the value of this element will not be saved with this object when serialization is used (for example, to save a binary object to a file, or send one across a network connection) the value of this element may change due to outside influences (other threads), so the compiler should not perform any caching optimizations specifies the level of access from other classes to this element - covered in depth later specifies that a method is required for a concrete extension of this class, but that the method will not be created at this level of inheritance - the class must be extended to realize the method for a class, specifies that the class itself may not be instantiated; only an extending class that is not abstract may be instantiated (a class must be abstract if one or more of it's methods is abstract) - covered in depth later the method is realized in native code (as opposed to Java code) - there is an external tool in the JDK for mapping functions from a DLL to these methods for a method, it should perform all calculations in strict floating point (some processors have the ability to perform floating point more accurately by storing intermediate results in a larger number of bits than the final result will have; while more accurate, this means that the results might differ across platforms) for a class, this means that all methods are strictfp
synchronized methods, code blocks
transient
fields
abstract
methods, classes
native
methods
strictfp
methods, classes
no synchronized code may be accessed from multiple threads for the same object instance at the same time
Data
The primitive data types store single values at some memory location that the compiler selects and maps to the variable name you declared
primitive values are not objects - they do not have fields or methods
A primitive value is stored at the named location, while an object is accessed using a reference
an object reference variable does not store the object's data directly - it stores a reference to the block of data, which is somewhere else in memory (technically, the reference stores the memory address of the object, but you never get to see or use the address) Primitives Data Types
Primitive Type boolean char byte short int long float double void
Storage Size 1 bit 16 bits 8 bits 16 bits 32 bits 64 bits 32 bits 64 bits None
Comments not usable mathematically, but can be used with logical and bitwise operators unsigned, not usable for math without converting to int signed signed signed signed signed signed not really a primitive, but worth including here
References
As we will see later, objects are stored differently than primitives. An object variable stores a reference to the object (the object is located at some other memory location, and the reference is something like a memory address)
Text Strings
A sequence of text, such as a name, an error message, etc., is known as a string In Java, the String class is used to hold a sequence of text characters A String object:
is accessed through a reference, since it is an object has a number of useful methods, for case-sensitive or case-insensitive comparisons, obtaining substrings, determining the number of characters, converting to upper or lower case, etc. is immutable; that is, once created it cannot be changed (but you can make your variable reference a different String object at any time)
Literal Values
A value typed into your code is called a literal value The compiler makes certain assumptions about literals:
true and false are literal boolean values null is a literal reference to nothing (for objects) a numeric value with no decimal places becomes an int, unless it is immediately assigned into a variable of a smaller type and falls within the valid range for that type a value with decimal places becomes a double to store a text character, you can put apostrophes around the character Effect
Code
char e = 'X'; creates a 16-bit variable to hold the Unicode value for the uppercase X character
You can add modifiers to values to instruct the compiler what type of value to create (note that all the modifiers described below can use either uppercase or lowercase letters) Modifying prefixes enable you to use a different number base
Prefix Effect
0X or 0x a base 16 value; the extra digits can be either uppercase or lowercase, as in char c = 0x1b;
Effect
note: using these prefixes will always result in number that is considered positive (so that 0x7F for a byte would be OK, but 0x80 would not, since the latter would have a value of 128, outside the range of byte) also note that a long value would need the L modifier as discussed below
L or l
note: an int value will always implicitly be promoted to a long when required, but the reverse is not true; the above notation is necessary because the literal value is larger than 32 bits F or f a float value, as in float f = 3.7F;
Escape Sequence \" \' \\ \uNNNN \NNN a quote mark an apostrophe a backslash
Resulting Character
a Unicode value, where N is a base 16 digit from 0 through F; valid values are \u0000 through \uFFFF a value expressed in octal; ranging from \000 to \377
The escape sequences can either be used for single characters or within strings of text
char c = '\u1234'; System.out.println("\t\tHello\n\t\tWorld");
like variables in that they have names, but not changeable once set
even though the variable's value is not changeable once a value has been established, you are allowed to set a unique value once local variables within methods may be declared as final their values may be set in an explicit initialization, in a separate line of code, or, for method parameters, as the value passed in when the method is called fields within a class may be declared as final their values may be set in an explicit initialization, in a separate line of code within an initialization block, or in a constructor
Fields of a class may be declared as public static final - that way they are available to other classes, but cannot be changed by those other classes
an example is Math.PI
Classes and methods may also be marked as final, we will cover this later
import java.io.*; public class FinalValues { final int f1 = 1; final int f2; { f2 = 2; } final int f3; public FinalValues(int i) { f3 = i; final int f4 = i; System.out.println("In constructor, f4 = " + f4); } public void useFinalParameter(final int f5) { System.out.println("f5 = " + f5); } public void printAll() { System.out.println("f1 = " + f1); System.out.println("f2 = " + f2); System.out.println("f3 = " + f3); } public static void main(String[] args) { FinalValues fv = new FinalValues(3); fv.useFinalParameter(5); fv.printAll(); } }
Mathematics in Java
Looks and behaves like algebra, using variable names and math symbols:
int a, b, c, temp; a = b/c + temp; b = c * (a - b);
Basic Rules
what goes on the left of the = sign is called an lvalue; only things that can accept a value can be an lvalue (usually this means a variable name - you can't have a calculation like a + b in front of the equal sign); math symbols are known as operators; they include: Operator + Purpose (Operation Performed) for addition for subtraction
Operator * / %
Purpose (Operation Performed) for multiplication for division for modulus (remainder after division)
Expressions
An expression is anything that can be evaluated to produce a value
Examples (note that the first few of these are not complete statements): Two simple expressions
a + 5 5/c
A statement is an expression; this one that contains another expression inside - the b + (5/c) part, which itself contains an expression inside it (the 5/c part)
a = b + (5/c);
Since an assignment statement (using the = sign) is an expression, it also yields a value (the value stored is considered the result of the expression), which allows things like this:
d = a = b + (5/c);
the value stored in a is the value of the expression b + (5/c) since an assignment expression's value is the value that was assigned, the same value is then stored in d the order of processing is as follows: 1. retrieve the value of b 2. retrieve the 5 stored somewhere in memory by the compiler 3. retrieve the value of c
4. 5. 6. 7.
perform 5 / c add the held value of b to the result of the above step store that value into the memory location for a store that same value into the memory location for d
Here is a moderately complicated expression; let's say that a, b, and c are all double variables, and that a is 5.0, b is 10.0, and c is 20.0:
d = a + b * Math.sqrt(c + 5);
since the c + 5 is in parentheses, the compiler creates code to evaluate that first but, to perform the c + 5 operation, both elements must be the same type of data, so the thing the compiler creates is a conversion for the 5 to 5.0 as a double
d = a + b * Math.sqrt(c + 5.0);
then the compiler creates code to evaluate 20.0 + 5.0 (at runtime it would become 25.0), reducing the expression to:
d = a + b * Math.sqrt(25.0);
next, the compiler adds code to call the Math.sqrt method to evaluate its result, which will be 5.0, so the expression reduces to:
d = a + b * 5.0;
note: the evaluated result of a method is known as the return value, or value returned multiplication gets done before addition, the compiler creates that code next, to reduce the expression to:
d = a + 50.0;
d = 55.0;
As implied by the examples we have seen so far, the order of evaluation of a complex expression is not necessarily from left to right
there is a concept called operator precedence that defines the order of operations
Operator Precedence
Operator precedence specifies the order of evaluation of an expression
every language has a "table of operator precedence" that is fairly long and complex
anything in parentheses gets evaluated before the result is related to what is outside the parentheses multiply or divide get done before add and subtract
Example
in the expression a = b + 5/c, the 5/c gets calculated first, then the result is added to b, then the overall result is stored in a the equal sign = is an operator; where on the table do you think it is located?
The basic rule programmers follow is: when in doubt about the order of precedence, use parentheses Try the following program:
Multiple Assignments
Every expression has a value. For an assignment expression, the value assigned is the expression's overall value. This enables chaining of assignments : x = y = z + 1; is the same as y = z + 1; x = y; i = (j = k + 1)/2; is the same as j = k + 1; i = j/2; Quite often, you may need to calculate a value involved in a test, but also store the value for later use
double x; if ( (x = Math.random()) < 0.5 ) { System.out.println(x);
You might wonder why not just generate the random number when we declare x? In this case, that would make sense, but in a loop the approach shown above might be easier
generates the random number and stores it in x as an expression, that results in the same value, which is then tested for less than 0.5, and the loop body executes if that is true the value of x is then available within the block after the loop body executes, another random number is generated as the process repeats
It is usually not necessary to code this way, but you will see it often
Order of Evaluation
The order of operand evaluation is always left to right, regardless of the precedence of the operators involved
Code Explanation
the operands are first evaluated in left to right order, so that the functions are called in the order getA(), then getB(), and, lastly, getC() but, the returned values are combined together by multiplying the results of getB() and getC(), and then adding the result from getA()
Bitwise Operators
Java has a number of operators for working with the individual bits within a value
Operator Example
Description Effect Bitwise AND, combines individual bits with an AND operation, so that in the resulting value, a bit position is only 1 if that position had a 1 for both operands 0...00000010 0...00000110 0...00000010 Bit Pattern
&
int a = 2; has the 2 bit set int b = 6; has the 2 and 4 bits set int c = a & results in 2 b; Bitwise OR, combines individual bits with an OR operation, so that in the resulting value, a bit position is 1 if that position had a 1 for either operand
int a = 2; has the 2 bit set int b = 4; has the 4 bit set int c = a | results in 6 b; Bitwise exclusive OR (XOR), combines individual bits so that any position that is the same in both operands yields a 0, any bits that differ yield a 1 in that position; this is often used in encryption, since repeating the operation on the result yields the original value again
int a = 3; has the 1 and 2 bits set int b = 6; has the 2 and 4 bits set int c = a ^ results in 5 b; int d = c ^ results in 3 again b; ~ Bitwise complement, reverses the state of all bits
0...00000011
Operator Example int a = 0; has no bits set int b = ~a; has all bits set
int b = a << now has the 16 bit set 2; >> right shift the bits by the second operand with sign-extension (if the first bit is a 1, new bits introduced to fill in on the left come in as 1 bits)
10...0000010
now has all bits set to 1 (the 0 rolled off the right end, and a 1 was int b = a >> added on the left to match the original leftmost bit; the resulting value 110...000001 1; is 63) >>> int a = -1; right shift the bits by the second operand without sign-extension (bits added on the left always come in as 0) has all bits set to 1 11...1111111 0000000...01
int b = a >>> now has all bits set to 0 except the rightmost (all bits except the first 31; rolled off the right end, and 0's were added on the left
Compound Operators
Combine multiple effects in one operation: calculation and storage into memory
Operator ++ Purpose (Operation Performed) increment a variable decrement a variable; note that ++ and -- can precede or follow a variable
--
if preceding (called prefix), apply the operator and then use the resulting value if following (called postfix), retrieve the value of the variable first, to use as the result of the expression, and then apply the operator += -= *= /= %= add an amount to a variable subtract an amount from a variable multiply a variable by an amount divide a variable by an amount set variable equal to remainder after division by an amount perform bitwise AND between left and right, store result into left operand perform bitwise OR between left and right, store result into left operand perform bitwise XOR between left and right, store result into left operand shift the variable's bits to the right by an amount with sign-extension shift the variable's bits to the right by an amount without sign-
&=
|=
^=
>>=
>>>=
Operator
<<=
y -= z + 5; y = y - (z + 5);
It is inevitable that a certification exam will ask a question that requires understanding the steps involved in a postfix increment or decrement: try the following program:
Code Explanation
in the first statement, i = i++;, the original value of i (0) is retrieved and held. Then, i is incremented. But, after that, the held value of 0 is put back into i, overwriting the 1!
in the second part, j = i++ + i;, the operands are evaluated from left to right, but each operand is fully evaluated before proceeding to the next. Which means that the increment part of i++ has taken effect before the second appearance of i in the equation, so that the expression reduces to 0 + 1 (recall that the previous operation resulted in i being 0)
The compiler must choose a specific type of data (either integer or floating-point, and the specific size) for each individual expression it evaluates within a statement
in general, the processor will choose the larger or more complex unit to work with in the first case the value 4 will be promoted to a double, which will then be used in the division the conversion is done one expression at a time within a statement; so, in the second example, the division will be performed with integer math, resulting in a value of 3, which will then be promoted to a double to finish the statement
The process of changing the data type of a value is known a typecasting (or casting)
a widening cast converts a smaller or less precise value into a larger or more precise type this is done automatically (the compiler does an implicit cast, as above) a narrowing cast converts a larger or more precise value into a smaller or less precise type (such as from double to int) - this must be coded with an explicit cast to code an explicit typecast, put the desired type in parentheses in front of the expression to be converted; for example:
the division will be evaluated as before, meaning the 4 is promoted to a double, and the result is a double but, a double can't be stored in a, so the cast to int is necessary note that casting is an operation, therefore it has a precedence (which is fairly high on the operator precedence table)
any expression involving these types, other than the compound assignment expressions, is done with int values, so that the result will always be an int
Try the following (it is the same as the earlier postfix increment example, using byte instead of int):
byte i = 0, j = 6, k; i++; k = i + j; System.out.println("i = " + i + ", j = " + j);
note that the increment expression is accepted by the compiler; it is the simple addition in the third line that causes an error
The Java Language Specification states the promotion rules as follows (note that this concept does not apply to all operators; again, the operators that include assignment do not use it): When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value of a numeric type, the following rules apply, in order, using widening conversions to convert operands as necessary:
if either operand is of type double, the other is converted to double. otherwise, if either operand is of type float, the other is converted to float. otherwise, if either operand is of type long, the other is converted to long. otherwise, both operands are converted to type int.
in procedural languages, these are called functions, but in OOP they are usually called methods almost all executable code is in some method technically, there is one other place an object-oriented program could have executable code, but that is an advanced topic examples: calculate a trigonometry function like cosine, print data on the screen, read from a file, open a window methods are defined by a name followed by parentheses inputs to the method go inside the parentheses; they are called parameters or arguments to the method
Using a method in your code, causing it to run, is known as calling the method A method call is an expression, so it may result in a value (the method call is evaluated like any other expression)
this value is called the return value, and the method is said to return a value the following is an example of a method used as an expression within a larger expression:
z = Math.sin(Math.PI / Math.sqrt(x));
Methods must be called with arguments that matching their specified form, known as the function signature
the signature is the combination of the name of the method with the pattern of its parameters the documentation for library-supplied methods will tell you the signature for those methods when you call a method, the name of the method and the parameters you pass to the it will determine which method will be called, based on the available signatures for each argument, Java expects a value - which could be a literal value, a variable, or expression; it must be either the correct type or a value that can be implicitly typecast to the correct type
they have complete access to all other elements of the class (fields and other methods, regardless of the access term on that element)
double y = Math.sqrt(x); System.out.println("Square root of " + x + " is " + y); double z = Math.sin(Math.PI / 2); System.out.println("Sine of pi/2 is " + z); } }
Code Explanation
This class calls two methods from the Math class: sqrt and sin, both of which expect one parameter which is a double. When we call sqrt and pass an integer, the compiler converts that to a double to provide the type of data that sqrt expects Note that even if your program does not call any methods, it has one method that will get called: main()
the definition of main() is that it provides a start point and end point for your program program execution starts with the first statement in main() if the last statement in main() gets executed, the program ends note that main() does have arguments (any other words typed on the command line)
Creating Methods
There are three things you need to decide for any method
Syntax
[modifiers] dataType methodName(parameterList) { methodBody return result; }
where emphasized words are concepts; fixed-font words are keywords, and brackets [] indicate optional elements: modifiers include the accessibility of this method from outside the class (public, private, protected, or left blank) as well as other possibilities listed on page 7 of this section dataType is a type of data, like int methodName is the name of your method parameterList is a comma-separated list of parameter names with their data types; each parameter is listed with its data type first, then its name methodBody is the set of statements that perform the task of the method return is a keyword that says to use the result expression value as the result of calling the method, and send that value back to the code that called the method (as an expression, a
call to a method evaluates to the returned value; i.e., calling Math.sqrt(4) evaluates to the value that sqrt returned) if a method declares that it returns a value of a certain type, then it must explicitly return a value of that type
Method Examples
public void sayHello() { System.out.println("Hello"); }
public methods are accessible to any other class void is a keyword for a returned data type that means no data at all - this method does not calculate a result the name of the method is sayHello this method could be called as follows: When Used
Code
sayHello(); from within the class x.sayHello(); from outside the class, for an instance x of this class
public void showNumber(int number) { System.out.println("The number is: " + number); }
again, this method does not calculate a result this method could be called as follows: Code When Used
showNumber(5); from within the class x.showNumber(5); from outside the class, for an instance x of this class
public int calculateSum(int num1, int num2) { int answer = num1 + num2; return answer; }
this method does calculate a result; the data type it calculates is int it must be given two parameters, both of which are int data this method could be called as follows: Code When Used
Code
When Used
int value = calculateSum(4, 6); from within the class int value = x.calculateSum(4, 6); from outside the class, for an instance x of this class
Return Values
Note that the listing of a data type word in front of a name is something we have seen before, in declaring variables
the purpose is the same - to state what type of data this element provides when used in an expression
The first statement below states that the value of a is an int, so that the compiler knows what memory size to allocate and what type of processing to use with it when it evaluates the second statement
int a; int b = a / 2;
The effect is no different using a method; recall the function signature (the first line) of our calculateSum method:
public int calculateSum(int num1, int num2)
it states that the result of evaluating calculateSum is an int, so that the compiler knows what memory size to allocate for the result, and what type of processing to use with it when it evaluates a statement like:
int b = calculateSum(4, 6) / 2;
when this statement gets processed, the calculateSum method will run and return its result (which will be the value 10 as an int) thus the statement in effect is reduced to:
int b = 10 / 2;
Method Parameters
Method parameters are also declarations
they declare a type of data received by the method, and also provide a name for each value so it can be used within the method
public int calculateSum(int num1, int num2) { int answer = num1 + num2; return answer; }
the parameter list declares two variables that will exist in this method: num1 and num2 the order is important - num1 will be the first value given to the method, num2 will be the second the difference between method parameter declarations and the variable declarations we saw before is that the method parameters receive their values when the method is called
Variable Scope
The variable scope rules are similar to those in C++ Variables can be declared at any point in your code, not just at the top of a block
local variables (those within methods) are not visible to any code that precedes the declaration object elements are visible to any code within the object, regardless of the order of declaration
Variables declared within a set of curly braces cease to exist after the closing brace (it is said that they go out of scope)
Variables can be declared in the control portion of a for loop, and will exist for the duration of the loop Parameters to a method are local variables within that method It is legal to use the same variable name in different scopes, as long as the two scopes have no irresolvable conflicts
non-overlapping scopes - for example, two different methods could each have a local variable called firstName overlapping scopes - it is valid for a method to have a variable whose name conflicts with a property name for that class - in that case, the local variable hides the property, but there is a special syntax that allows the method to access the property; we will cover this later it is legal for a method and a property of a class to have the same name, although it is not considered a good practice to do so an example of an irresolvable conflict is declaring a local variable within a block when the same name is already in scope in that method as a local variable
public class MethodExample { public static void sayHello() { System.out.println("Hello"); } public static void showNumber(int number) { System.out.println("The number is: " + number); } public static int calculateSum(int num1, int num2) { int answer = num1 + num2; return answer; } public static void main(String[] args) { sayHello(); showNumber(5); int b = calculateSum(4, 6); System.out.println("The sum of 4 and 6 is:" + b); b = calculateSum(4, 6) / 2; System.out.println("That divided by 2 is: " + b); } }
We will cover the concept of static elements later, but, for now, since main is static, the methods it calls must be static as well
About Java's basic syntax rules, variables and their declaration, and primitive types To write simple statements using variables and operators. To understand the rules that apply when data is converted from one type to another. To declare, write, and use simple methods
Interfaces
In this lesson of the Java tutorial, you will learn... 1. Understand the concept of interfaces 2. Define and write code using your own interfaces 3. Use interfaces in the Java API
Interfaces
Interfaces define a standardized set of commands that a class will obey The commands are a set of methods that a class implements The interface definition states the names of the methods and their return types and argument signatures
there is no executable body for any method - that is left to each class that implements the interface
Once a class implements an interface, the Java compiler knows that an instance of the class will contain the specified set of methods
therefore, it will allow you to call those methods for an object referenced by a variable whose type is the interface
Implementing an interface enables a class to be "plugged in" in any situation that requires a specific behavior (manifested through the set of methods) An analogy: a serial interface on a computer defines a set of pin/wire assignments and the control signals that will be used
the actual devices that can be used may do entirely different tasks: mouse, modem, etc. but they are all controlled through the same digital instruction mechanism; the individual wires are specified to carry specific signals
Using an interface rather than inheritance to specify a certain set of methods allows a class to inherit from some other class
in other words, if a class needs two different sets of methods, so it can behave like two different types of things, it could inherit one set from class A, and use an interface B to specify the other you could then reference one of these objects with either an A reference or a B reference
Interfaces can also specify constants that are public, static, and final
define it like a Java class, in its own file that matches the interface name use the keyword interface instead of class declare methods using the same approach as abstract methods o note the semicolon after each method declaration - and that no executable code is supplied(and no curly braces) o the elements will automatically be public and abstract, and cannot have any other state; it is OK to specify those terms, but not necessary (usually public is specified and abstract is not - that makes it easy to copy the list of methods, paste them into a class, and modify them ) The access level for the entire interface is usually public o it may be omitted, in which case the interface is only available to other classes in the same package (i.e., in the same directory) o note, for the sake of completeness, there are situations where the interface definition could be protected or private; these involve what are called inner classes
Syntax
[modifiers] interface InterfaceName { // declaring methods [public abstract] returnType methodName1(arguments); // defining constants [public static final] type propertyName = value; }
Example:
Code Explanation
This interface requires only one method. Any class implementing Printable must contain a public void printall() method in order to compile Because the above interface is defined as public, its definition must be in its own file, even though that file will be tiny
An interface definition may also define properties that are automatically public static final these are used as constants
Implementing Interfaces
A class definition may, in addition to whatever else it does, implement one or more interfaces Once a class states that it implements an interface, it must supply all the methods defined for that interface, complete with executable code
note: it actually does not have to implement all of them, but in that case the class cannot be instantiated- it must be declared as an abstract class that can only be used as a base class (where some derived class would then fully implement the interface)
To implement an interface:
add that the class implements the interface to the class declaration add the methods specified by the interface to the body of the class o note that you do need to specify the access terms on methods in a class that implements an interface
Syntax
[modifiers] class ClassName implements InterfaceName { any desired properties // implement required methods [modifiers] returnType methodName1(arguments) { executable code } any other desired methods }
It is important to note that a class may implement an interface in addition to whatever else it might do, so it could have additional properties and methods not associated with the interface A class may implement more than one interface - that merely adds to the list of required methods
Syntax
[modifiers] class ClassName implements Interface1Name, Interface2Name {
Code Explanation
This file contains two classes with package access. Both implement the Printable interface, but are otherwise not related. Stock has another method not related to Printable.
interfaces are listed like classes in the API documentation they compile to a .class file, and get loaded by the same process that loads true classes
Since a class that implements an interface is a class in all other respects, you can create a reference variable for that class, as usual You can also create a reference variable whose type is the interface name
only the methods defined in the interface are visible through a variable whose type is the interface o if you do this, the only things you can access with that variable are the interface methods o for a Printable variable containing a Stock instance, the sell method is not visible, since it is not declared in Printable any constants defined by the interface can be accessed without a prefix from code within the class, since implementing the interface makes them part of this class for using a variable whose type is an interface, the same situations apply for as were discussed in the section on inheritance
Example:
both Person and Stock implement Printable therefore, we can create a reference variable to a Printable, and assign either a Person or a Stock object to it we can then call the printAll() method from the Printable reference variable, since the compiler knows that method will exist, no matter which type of object is actually stored in the variable
or
pr = s;
or
pr = new Person();
note that you cannot call any of the additional methods that are not defined by the interface
Code Explanation
we cannot directly call the sell() method when pr refers to a Stock, since the compiler would not associate it with a variable whose type was Printable
Note: to compile this, use *.java; since the name of the file containing Stock and Person is PrintableThings.java, the compiler won't be able to find those classes, since it would be looking for Person.java and Stock.java. Note: you can test the type of object actually contained in an interface reference, and typecast it back to that type
they are guaranteed to have the necessary methods available it is a good practice to specify that the derived class implements the interface, just for selfdocumentation of the code (also for purposes of javadoc, if the base class is not in the same group of files)
the new interface then adds properties and methods to the existing (base) definition a class that implements the new interface must implement all methods from the base interface as well as all the additional methods from the new interface definition
The following interface extends the Printable interface and adds another required method (the new method overloads printAll to print to a specified destination instead of to System.out):
It turns out that our hypothetical system is to be used for all payments our company makes, not just payroll checks- things like invoices will be paid through the system as well
1. Create a finance package, and within it create an interface called Payable
2. 3. 4. 5.
6.
It should define the public String getPayInfo() method that our employee classes already implement Specify that all the employee classes implement Payable The Solutions\Payroll-Interfaces01 directory contains a package called vendors with a class named Invoice - copy this directory to your working directory Modify the payroll program by adding an array of several invoices (you can just hard-code them) Create an array of type Payable whose size is the sum of the employee and invoice arrays sizes, then use System.arraycopy twice to combine the employee and invoice arrays into it (remember that for the second array, the starting point for the destination array will be the first array's length value) Loop through the combined array to get and print the payment info for each item
an object that can generate an event maintains a list of objects that would like to listen for that event (they will be notified when the event occurs by having one of their methods called) the object that generates the event fires it by going through its list of objects that want to handle the event, and calling a specified interface method for each object a class may handle an event if it implements the interface that is expected for that event therefore it will have the specified method you register an object to handle an event by passing a reference to it to the eventgenerating object's method that adds a handler
the handler interface would probably be named XXXListener the method to register a listener would usually be called addXXXListener the method generating the event probably has a protected utility method called fireXXXEvent that it uses to trigger the event notifications (and it is available for you to call if you extend the class)
The ActionListener interface is used for GUI events like button clicks
the event is fired by the GUI object calling the actionPerformed method for any registered listeners (the code to do this is already built into the GUI classes, and the Java API defines the interface shown below)
it can either register itself with the event-generating object, or code outside the class can register it - the example below shows how it would register itself using this
public class MyClass implements ActionListener { ... public void actionPerformed(ActionEvent e) { System.out.println("Event occurred"); } someOtherMethod() { guiComponent.addActionListener(this); } }
For the class that fires the event, registering is done with the addActionListener(ActionListener) method, which receives a reference to an ActionListener object
it adds that reference to a list (maybe a java.util.Vector) of listeners when the time comes to fire the event, it walks through the list, calling actionPerformed() for each element on the list (and passing a reference to an event object that it creates)
For the sake of completeness, when the listener interface has multiple methods, there are often abstract classes that implement most or all of the methods as do-nothing methods - so that all you need to do is extend the class and implement the methods that you choose
this is particularly useful for gaining the add and remove listener logic, which is implemented in the base class
it uses a Model-View-Controller approach to separate these sections of logic into individual classes the TableModel interface defines a set of methods that allow a JTable (the controller) to query a data model to find out information in order to display it the interface forms a framework for a discussion that will take place between the controller and the model (like, "How many rows do you have?" and, "How many columns?", followed by "What's the value at column 0, row 0?", etc.)
You can see the conversation that will take place between the controller and the model
the controller will ask the model for the number of rows and columns, and, with that information, ask for the value at each location it will ask for the type of data with getColumnClass, so it can determine from its settings how to display the values (instances of Number, which Integer, Double, etc., extend, get right-aligned, Boolean columns use a check box, all others get left-aligned - these settings are configurable) it will get a heading for each column with getColumnName if a cell is double-clicked, it can ask if the cell is editable with isCellEditable o if it is, when the user is done editing, it can put the new data into the model using setValueAt
public class TableModelExample { public static void main(String[] args) { DemoTableModel model = new DemoTableModel(); new TableGUI("Table Model Example", model).setVisible(true); new TableConsole(model); new TableHTML(model); } } class DemoTableModel extends AbstractTableModel { String[] titles = { "Name", "Active", "Grade" }; String[] names = { "Mary", "Joe", "Sue" }; Boolean[] actives = { new Boolean(true), new Boolean(false), new Boolean(true) }; Integer[] grades = { new Integer(99), new Integer(87), new Integer(89) }; public int getRowCount() { return names.length; } public int getColumnCount() { return 3; } public String getColumnName(int col) { return titles[col]; } public Object getValueAt(int row, int column) { if (column == 0) return names[row]; else if (column == 1) return actives[row]; else return grades[row]; } public void setValueAt(Object v, int row, int column) {} public Class getColumnClass(int column) { if (column == 0) return String.class; else if (column == 1) return Boolean.class; else return Integer.class; } public boolean isCellEditable(int row, int column) { return false; }
} class TableGUI extends JFrame { public TableGUI(String title, DemoTableModel model) { super(title); JTable jt; this.setDefaultCloseOperation(EXIT_ON_CLOSE); jt = new JTable(model); setSize(600,170); getContentPane().add(jt); } } class TableConsole { TableModel model; public TableConsole(TableModel model) { int rows = model.getRowCount(); int cols = model.getColumnCount(); for (int c = 0; c < cols; c++) { System.out.print(fixedStringLength(model.getColumnName(c), 15)); } System.out.println(); System.out.println("-------------- -------------- -------------- "); for (int r = 0; r < rows; r++) { for (int c = 0; c < cols; c++) { System.out.print(fixedStringLength(model.getValueAt(r, c).toString(), 15)); } System.out.println(); } } private String fixedStringLength(String in, int size) { if (in.length() > size) in = in.substring(0, 15); char[] blankArray = new char[size - in.length()]; for (int i = 0; i < blankArray.length; i++) blankArray[i] = ' '; return in + String.valueOf(blankArray); } } class TableHTML { TableModel model; public TableHTML(TableModel model) { java.io.PrintStream out = System.out; int rows = model.getRowCount(); int cols = model.getColumnCount(); out.println("<html><Head><title>My Table</title></head>"); out.println("<body><table border='1' cellpadding='8' cellspacing='0'><tr>"); for (int c = 0; c < cols; c++) { out.print("<th>" + model.getColumnName(c) + "</th>");
} out.println("</tr>"); for (int r = 0; r < rows; r++) { out.println("<tr>"); for (int c = 0; c < cols; c++) { System.out.print("<td>" + model.getValueAt(r, c) + "</td>"); } out.println("</tr>"); } out.println("</table></body></html>"); } }
Code Explanation
For convenience, all the classes are in one file. The DemoTableModel class implements TableModel by extending AbstractTableModel, thus gaining implementations of several methods (like those relating to model change event listener lists), then adding the remaining methods. The model is based on parallel arrays of student data: name, grade, and active or not- each array represents one column of data, and element 0 in each array is the same student. The titles array holds column names. getColumnCount returns 3, because we know that in advance. getRowCount returns the length of one of the data arrays. For getColumnName, we return an appropriate string from the titles array. For getValueAt, we pick an array based on the column number, and return the element at the row index. getColumnClass returns a class object that matches the type of data for each array. isCellEditable returns false, and setValueAt does nothing, because our model is not editable. We then have three possible views of the data: a Swing GUI view that uses a JTable, a console view that prints column-aligned data, and an HTML view that produces HTML code to the console (you can copy that and paste it into a file to view in a browser, like in tablemodel.html). Since the JTable is the whole reason TableModel exists, it knows what to do with the model. The TableConsole and TableHTML view objects have to explicitly call the appropriate methods in order to display the data.
Marker Interfaces
It is actually possible to have an interface that requires no methods at all! This creates what is called a marker interface A declaration that a class implements the interface makes it an instance of that interface, so that it can be passed as a parameter to a method expecting an instance of the interface, or as a return value from a method that declares it returns an instance of the interface. An example from the API is Serializable
an object that implements Serializable may be turned into a serial data stream, perhaps to save in a file or send across a network connection the writeObject method of ObjectOutputStream accepts a parameter whose type is Object, but throws an exception if it doesn't implement Serializable the serialization mechanism is recursive, so not only must the object be an instance of Serializable, but any of its object fields must also reference objects that are Serializable (or marked as transient), and any of their fields ...
Interfaces Conclusion
In this lesson of the Java tutorial you have learned:
To continue to learn Java go to the top of this page and click on the next lesson in this Java Tutorial's Table of Contents.
Java Objects
In this lesson of the Java tutorial, you will learn... 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. General Object-Oriented concepts To declare object classes, defining methods and properties To create instances of objects and use them in a program To access objects using reference variables To define different protection levels for elements To define constructors To overload methods and constructors To use the this self-reference To declare and use static elements To create packages of classes
Objects
In general, the concept of an object is: a collection of data along with the functions to work with that data
as opposed to purely procedural languages where the data and functions are separate, and the data is passed to the function to work with
a class is an object definition, containing the data and function elements necessary to create an object an instance of an object is one object created from the class definition (the process is known as instantiation) the data and function elements are known as members data members are also known as fields, properties, or attributes, and function members as methods
Methods can work with any properties of an object, as well as any other methods A constructor is a function that defines the steps necessary to instantiate one object of that class
if you do not explicitly create one, a default constructor that does nothing will be created automatically
Each class should generally be defined in its own file if it is to be used by other classes
the file name must match the name of the class, plus a .java extension
The data members of a class may be any type of data, objects or primitives
It is traditional in Java that only class names begin with capital letters
variable names, both object and primitive, begin with lowercase letters, as do method names multi-word names, like first name, are done in Camel-case (as in firstName)
Object-Oriented Languages
For a whirlwind tour of OOP, an object-oriented language is supposed to include three major concepts: Encapsulation - that data and the functions to work with that data are contained within the same entity; encapsulation includes another concept: data hiding or protection - where direct access to data is restricted in favor of methods that manipulate the data Polymorphism - that there can be different forms of the same thing, so that you could have one variable that could store several different types of objects; or a method that accepts no arguments and another method with the exact same name that accepts an integer argument (and maybe another that accepts a string and a double-precision argument, etc.). Inheritance - that an object definition can use another object definition as a starting point and build upon that base object (in which case the original object definition is called the base class, parent class, or superclass and the new class is called the derived class, the child class, or subclass, respectively) - note that a derived class can be used as a base for further inheritance, creating a chain Java uses all three of these concepts Java does not allow any code that is not part of an object - all code in your program must be inside a class definition Java forces inheritance on every class - if you do not explicitly inherit from a class, then by default Java assumes that you are inheriting from the class called Object (which does not do much, but does have several useful methods)
if you think about this, it implies that every class is descended from Object, since whatever class you inherit from must have inherited from something, which would be either Object or something that inherited from something, etc. the concept of polymorphism implies that you could store any type of object in a variable whose type was Object
Object-Oriented Programs
An object-oriented program replaces the concept of a linear sequence of steps with steps that create instances of defend types of objects, connect them together, and set them to communicating with each other
For example, in an HR/Payroll application, we might have object classes that represent employees, dependents, checks, departments, financial accounts, etc The act of creating a check for an employee could trigger a number of actions:
update the employee's accumulated pay, etc., fields - done in an employee object update accumulated department totals - performed in a department object debit a financial account - done in an account object cause a physical check to be printed - a check object would be created encapsulating the information, and sent to a printing module (in some sort of object dedicated to similar generic operations) upon successful printing of the check, notifications would be sent to the above objects to finalize their operations
Encapsulation is the concept that the data and operations that work on or with that data are bundled together into one unit - the object Objects are said to have state and behavior
the state is the current set of values for all the data values terms commonly used to describe the state values are: o data members o fields o properties o attributes the behavior is the set of operations that the object can perform (the functional code for the object) o commonly called methods, but also called functions sometimes
Encapsulation
In a procedural program, the executable code is usually kept in a separate area from the data values
in general, the programmer will tell the code for an entity where it's data is
In an object-oriented program, it will appear to the programmer that the data values are kept with the executable code
each object has a memory area, which can be viewed as having a data block and a code block (note that this is a dramatic simplification - in practice the data is indeed kept separate from the data, but the compiler and/or runtime environment handles the details necessary to match an object's code with its data) an entity's code automatically knows where its data is
Encapsulation is often said to include the concept of data hiding, where the data elements of an object are not directly invisible to the outside world. Instead, methods are provided to retrieve and set the values of the data elements
forcing external code to go through code inside the class allows for validation of data; for example, if a field must have a value that is greater than or equal to zero, the method to set that field can perform a test on incoming data to ensure that it is valid
We would like to develop a simple employee database system that will include the ability to pay an employee (print a check for them, and processing necessary for bookeeping)
1. As a first step, we will define a type of object to represent an employee o what data fields would we be likely to need (names and the type of data they would hold) o what methods might be associated with an employee's data? Where is the solution?
the variable sb now holds an instantiated StringBuffer object (StringBuffer is a class from the Java API) creating a String does not require the new keyword, text in quotes automatically becomes a String object:
the dot operator ( . ) following an object reference gives access to the elements of that object
so, if we know that the String class has a method toUpperCase() that returns an uppercase version of the text, we can now call that method to get our message in uppercase:
s.toUpperCase();
System.out.println(s.toUpperCase());
References
When you create an object, it occupies some memory location that the JVM allocates at runtime If you then have a reference and set it equal to that object, the variables memory location stores the numeric address of the memory location where the object is stored (often it is said that it points to the objects memory location; it is more appropriate to say that it references the object) If you set one object variable equal to another, you do not have two copies of the object you have one object and two variables that point to that object If you had the following:
MyClass myObject = new MyClass(); MyClass yourObject = myObject;
You would not end up with two copies of the same data, you would end up with two references to the same object (since all you really did was store another copy of the original objects memory address) So, if you then changed the properties of myObject, the properties as seen through yourObject would change as well
Note: there is a clone() method available to copy an object's contents to a new object Although this is a technicality, it is an important one: certain Java classes are immutable, or final, that is, they cannot be changed once they are created
String objects are immutable, as are the wrapper classes that hold primitive data types inside objects you can still set a String reference variable to a new value, but what you are doing is setting the reference to point to a different object the important point to note is that if there were other references to the original String, they would be unchanged - this follows from how references work, but is counter to how some languages work
Reference Example
In the following code the new keyword creates an object, in this case a new StringBuffer object
the first line creates a StringBuffer object containing the text Hello, then creates a reference variable called sb1 that points to that new object
the second line creates a reference variable called sb2 that points to nothing (it is set to null) the third line then sets sb2 to point to the same object that sb1 points to
the last line changes sb2; the effect of this change is seen via sb1 as well
Reference Expressions
A reference is a simple form of expression. References from more complex expressions may be used as well. For, example, with an array of String references called names, a method for one element can be called in this manner:
names[1].toUpperCase()
Similarly, if a method returns a reference, a method may be called directly on the returned value
Code Explanation
The StringBuffer.append method returns a reference to the same StringBuffer object, so that another call to append or any other method can be chained to the result.
Defining a Class
The basic syntax for defining a class is:
Syntax
[modifiers] class ClassName { (property definitions, constructors, and methods go here) }
Example (for overall format only, we will examine the pieces later):
Normally the access term for the class should be public, which means that the class can be used in other classes
a public class definition must be in a file with a name that matches the class name, but classes with other access levels do not have that requirement
Access to Data
Class definitions may have different access levels - this determines where an object of the class may be instantiated or otherwise used
class definitions are usually made freely available to all code, defined as public
All data and function members in a class are available to any code written for that class
note that the normal scope rules for local variables apply to Java - that is, a method's internal variables are never available to other methods
There are four possible access states, three are declared with access keywords
public - the member may be freely accessed by code from any other class protected - the member may not be accessed by code from any other class, except: o classes that inherit from this class o classes in the same package (a package is a collection of classes - basically all the classes stored in the same directory) private - the member may not be accessed by code in any class, including classes that inherit from this one there is a fourth possibility, the default access used if you use no access word at all o any code in the same package (the same directory) can access the member o this type of access is often called package access, and is also sometimes called default or friendly access
Example - the example from the previous page defines a class that will be publicly available, so that any class could instantiate one
the class listed below can use that class in its code, but cannot directly access the title or itemCode properties, so it must call the setTitle and setItemCode methods to set properties, and getTitle and getItemCode to retrieve properties:
if the item is public, then the name of the item may be written within code for any other class if the item is private, then the name of the item may not be written within the code for any other class package access is the default if no access term is specified; this allows the name of the item to be written within code for any class in the same package (which maps to the same directory)
if the item is protected, then the name of the item may not be written within the code for any other class, except one that extends this class, or a class in the same package
For example:
if a class definition is public, then you can write the name of the class in code in some other class (so you can use the class) if it is private, then you can't write the name in any other class, so you couldn't use it (in fact, a private class definition can only be used in one very special situation, to be covered later)
if the class is public, and contains a public element, you can write the name of the class in another class, and you can write the name of the element in that class as well - and if the element is private, then you can't write its name, so you can't use it so, the UseBookBasic class code, which has a BookBasic variable b, can use b.getItemCode() and b.setItemCode(5011), but not b.itemCode
Note: this does not mean that a private item cannot be affected by the code in another class; it just can't have its name written in that other class
the example on the previous page shows how public methods can provide controlled access to a private element - in this case to ensure that the value of itemCode is never set to a negative value
note that multiple members of the same type may be defined with one statement variables may be given initializing values when declared primitive data elements are initialized to 0 unless explicitly set to a value (and remember that for a boolean value a 0 bit means false) member elements that are object reference variables are automatically set to null if not given a specific initial value (null is a keyword)
this class has integer variable itemCode and a reference to a String object called title neither of these can be directly accessed from outside the class definition, since they are private
note that in Java, unlike C++, the method body must be defined when the function is declared - you can't postpone that until later
Syntax
[modifiers] class ClassName { [modifiers] dataType propertyName1, propertyName2, . . . ; [modifiers] dataType propertyName3 = value, . . . ; [modifiers] returnType methodName(paramType paramName, (method body code goes here) } (more methods here) } . . . ) {
Methods may freely access all data and function members of the class
get methods do not take any parameters; set methods take one parameter whose type matches the type of the property note that for boolean true/false values, the convention also uses is and has as prefixes for the get methods (as in isEnabled() for a property called enabled)
It is also considered a good practice to reuse existing methods for any steps that work with data in an way other than simple retrieval
for example, if we had a method that accepted both itemCode and title, we would call the setItemCode() and setTitle() methods rather than access those properties directly that way if our approach to setting a value changes, the effect is automatically applied through all methods that do that
Java Beans
If you follow the standard naming conventions, you are most of the way to creating a Java Bean class
a bean is an object that can be created and used by various tools, both at development time and at run time Java has a mechanism known as reflection, inspection or introspection that allows for classes to be instantiated and used without knowing at compile time what the class name is o a bean can be instantiated using a String variable containing the class name o or a bean can be delivered to an application, for example, across a network connection o at runtime, for any object, its methods and fields can be determined by the JVM, as it inspects the object o tools can then match field names to get and set methods and treat the fields as properties (to this point, we have used the terms fields and properties more or less interchangeably - in bean-speak fields are data values and properties are private fields that can be accesses by set and/or get methods) example uses of beans include: o Java-based GUI development tools can create instances of GUI component beans such as text fields, radio buttons, etc., and create a properties table where the programmer can enter values into text fields for values such as background color, foreground color, text value, etc. (keep in mind that the environment's JVM can inspect the component objects) o Java Server Pages can instantiate a bean and set and retrieve properties to display in a dynamic web page to be a bean, a class must: o have a constructor that takes no parameters (the object will be created empty, and populated from the set methods - if there was a Rectangle class, for example, with height and width properties that were int, the tool wouldn't know how to call a constructor that took both parameters (which is the height and which is the width?) o follow the naming convention stated above o a bean can also have additional methods that code with advance knowledge of the class can call
Bean Properties
Properties are defined by public get and set methods, and usually map to private fields
a read-only property would have a get method, but no method to set the value - the property might or might not be backed by a field
Code Explanation
The class has a constructor that takes no parameters, plus methods to get and set the height and width. The area is a read-only property that is not backed by a field - it is calculated each time it is needed. A Java Server Page might instantiate a Rectangle bean, populate the height and width from values submitted from a form, and send back a page showing the area of the rectangle.
less often, you might encounter a write-only property - a simplistic example might be a security bean that uses a key to encrypt and decrypt messages: you could set the key, but not retrieve it (and other methods would set an incoming encrypted message and retrieve the decrypted version, or set an outgoing message and retrieve the encrypted result)
After review with management, it is decided that we will store the following information for each employee:
employee ID (an integral number, automatically assigned when a new employee is added) first name and last name department number (an integral value, call it dept) pay rate (a floating-point value, using a double)
a method called getPayInfo() that will return a sentence with the employee's name, id, department, and check amount a method called getFullName() that will return the first and last names separated by a space
1. Define a class called Employee with these characteristics, using standard practices for limiting data access and for method naming 2. In order to be useful, there should be methods to set and get all properties (except setting the employee id, which will happen automatically in a manner to be determined later; for now, just let it default to 0) 3. Create a class called Payroll with a main method, it should: o instantiate an Employee object o set values for all properties o call the getPayInfo() method to see the results Where is the solution?
Constructors
Every class should have at least one method: the constructor
this specifies code that must run to instantiate (usually to initialize) a new object from the class definition
the name of the constructor is the the same as the name of the class constructors have no return type and do not return a value they make take input parameters, usually to populate the fields for the new object
they may use the standard access keywords - usually they are public (but in some circumstances involving inheritance they are sometimes protected or private)
The methods in an object are available at construction time. While a constructor could set properties directly, it is considered a better practice to call the set methods to store any values. That way, any validation necessary on the data can be accomplished without duplicating the validating code.
Code Explanation
Note how the constructor can make use of the existing methods.
note that the type of the object reference variable must match the type of the class being instantiated (or, for later, match a parent of that class) you can pass parameters as long as the parameter list matches a constructor for that class note that while the object reference is often stored in a variable, it does not have to be an object can be instantiated in any situation where an object reference could be used, for example:
When a new instance is created, the following sequence of events takes place (note that this includes only concepts we have covered thus far - later we will expand the sequence as we cover additional topics)
1. 2. 3. 4. 5. memory is allocated in an appropriately sized block the entire block is set to binary zeros (so every property is implicitly initialized to 0) explicit initializations of properties take place the constructor runs the expression that created the instance evaluates to the address of the block
if you still want to have a no-argument constructor that does nothing, you must explicitly write it try modifying UseBookWithConstructor.java to add line like Book c = new Book();
Method Overloading
Methods can be overloaded to have several versions, all with the same name
the difference is in the parameter lists, also known as the function signature differences in return types are not enough to create a second version of a function, the parameter lists must be different
Syntax
[modifiers] returnType functionName(paramlist) { . . . } [modifiers] returnType functionName(differentParamList) { . . . }
Constructors are often overloaded, so that an object can be instantiated from different combinations of parameters This is an example of polymorphism - the concept that the same name may have several forms. Method overloading produces a functional polymorphism, since the same method name can be used in different ways. While polymorphism is mainly used to describe having one variable that can store different but related types due to inheritance, the concept also applies to overloaded methods at a smaller scale. Continuing our example:
if you have a method that receives an input parameter String s, but s is already a member variable String reference
class X { String s; public void setS(String s) { this.s = s; } } o o o o
within the function, the parameter s is a local variable that will disappear when the function ends it hides the existence of the s member field but, we can pass the local variable's value into the field s by using the this reference to resolve s as the one that belongs to this object some programmers always use this approach with constructor functions and set methods - the benefit is that the code is more self-documenting, since it would use the most appropriate variable name in both the class definition and in the method argument
Used when the object's code needs to pass a reference to itself to the outside
say you are creating MyClass some other class, YourClass, has a public method called useMyClass that needs a reference to a MyClass object; in other words, something like:
The this keyword is also used in a constructor function to call another constructor from the same class
a function that is not a constructor can only call other functions that are not constructors (although it can still cause a constructor to run by instantiating an object) a constructor may only call one other constructor, and it must be done as the first line in the function the this keyword is used instead of the name of the constructor, then arguments are passed in a normal fashion
The following example uses this to provide the object with a reference to itself, as well as to chain to another constructor:
Code Explanation
The constructor that only accepts the title calls the other constructor, passing 0 as the item code. It would also be possible to run set up the chain of constructors in the reverse direction, as in:
public BookUsingThis(int itemCode, String title) { this(title); setItemCode(itemCode); } public BookUsingThis(String title) { setTitle(title); }
This approach is good if the default values of the fields (either zero or as set by an initializer) are acceptable - note that the constructor that accepts only title never sets the item code
Code Explanation
The second book uses the constructor that accepts only the title. Since the new operator results in a reference to the book, we can chain a call to display to that result.
static Elements
The keyword static states that one and only one of this element should be available at all times - whether there is one object of the class instantiated, many objects, or none at all
Syntax
[modifiers] static dataType propertyName; [modifiers] static returnType methodName(paramType paramName, . . . )
If a data member is static, there is one memory location that is shared among all instances of a class
this allows the separate instances of one class a way of sharing data with each other that memory location exists even if no objects of the class exist - this is useful for creating constants any initialization of this value occurs just once, when the class is loaded into the JVM
If a method is static and public, then it is available even when no objects have been instantiated
this is used in the Java API for math functions like the random number function and trigonometric functions - they have to be part of a class, but you wouldn't want to have to instantiate some special object just to generate a single random number or calculate a cosine o for more sophisticated random number generation, where repeatability of a sequence of random values might be desirable, there is a Random class one caveat with this approach is that the function cannot access any of the other elements (data members or methods) that are not also static, since it is not guaranteed that they will exist when the function is called such an element is referenced using the name of the class, a dot, then the element name:
3. What happens when each new Employee gets instantiated? Where is the solution?
Garbage Collection
Java takes care of reclaiming memory that is no longer in use Your program is not making memory-allocation calls directly to the operating system - the JVM requests a fairly large block at start time, and handles memory allocation from that block
when necessary, it can request additional blocks from the OS there are command line options to set the initial, increment, and maximum sizes
When an object is no longer reachable through your code, it becomes subject to garbage collection
the JVM has a low-priority thread that checks the graph of objects to find orphaned objects those that are found are marked as available to be collected a separate process will run when necessary to reclaim that memory if your program has small memory requirements, it is possible that garbage collection will never run
note that this may not have any effect; it is not guaranteed to run when you ask - the call is merely a request
You can specify code to run when an object is collected by writing a finalize() method in a class
note that there is no guarantee that this method will ever run when the program ends, any objects still reachable will not be collected, nor will any objects marked for collection but not yet collected - thus finalization will not occur for those objects
Java Packages
As you have seen, Java programs may involve a large number of files Packages help organize files within a program, as well as to collect objects into groups to improve reusability of code
package names correspond to directory names a dot is used between levels of a multilevel structure searching for files starts at the root level of the structure during compiling or class-load at runtime you can't use packages or directory structures without explicitly placing a class in a package via your code classes are always referenced from the root of the structure, and the fully-qualified name of the class contains the relative path elements to reach the class from the root point, separated by dot characters
To assign a class to a package, use a package statement as the first non-blank, noncomment line of code
package test; package test.util;
puts this class in the package called test in order to be found, the class file must be in a directory named test that directory must be located in one of the classpath locations puts this class in the package called test.util in order to be found, the class file must be in a subdirectory of the test directory named util; test must be located in one of the classpath locations
XYZ.java should be in a directory called test that is located within a directory listed in our CLASSPATH the fully-qualified name of the class is test.XYZ
When the compiler and JVM look for the files, they will search every CLASSPATH entry for a directory called test containing XYZ.java (or XYZ.class, if that is what is needed)
you can use the -d option with javac to put the class files into a separate, parallel directory structure Syntax
it will start the structure at the directory called rootofstructure it will build the directories if they don't already exist o in earlier versions of the JDK, all the source code, regardless of package, had to be in the same directory for that to work
To run an executable Java class that belongs to a package, your command prompt should be at the directory level that matches the root of the package structure
Example - the directory C:\MyProject is the root level of a package structure, and the main class, XYZ.class, is in the package called test (therefore test is a subdirectory of MyProject) To run XYZ.class, the command line would look like the following:
C:\MyProject>java test.XYZ
explicitly use the fully-qualified name of the class import either that specific class or the entire package
it contains BookstoreWithPackage.java (the main class) within that is a directory called types, which contains Book.java
The package statement must be the first non-comment, non-blank line in the file. Referencing Packaged Classes - Importing and Fully-Qualified Names In BookstoreWithPackage.java, you could import the entire types package, or just the class(es) you need
import types.*;
or
import types.BookWithPackage;
then
public class BookstoreWithPackage { public static void main(String[] args) { BookWithPackage b = new BookWithPackage("My Favorite Programs"); . . . } }
Or, instead of importing, you could explicitly reference the class by its full name, which precedes the class name with the package structure (using a dot character as the directory separator)
public class BookstoreWithPackage { public static void main(String[] args) { types.BookWithPackage b = new types.BookWithPackage("My Favorite Programs"); . . . } }
This approach is necessary if your program uses two classes with the same name (such as java.sql.Date and java.util.Date) All classes in the Java API are in packages. We have not had to deal with imports to this point because the package java.lang is special - it does not need to be imported. (This is where System, String, the numeric wrapper classes like Integer, and a few more generally useful classes reside.) The package at the root level is called the default package. When the main Class is in a Package If your main class is in a package, then it must be compiled and run from the root of the structure For example, say your directory C:\Bookstore is the root of your project, but it contains no classes
it contains a subdirectory called bookstore, which contains Bookstore.java (the main class)
if that directory contained the types directory, the remainder of the code would be as before
To compile the program from the C:\Bookstore directory, use the standard operating system directory separator character:
javac bookstore\Bookstore.java
To run the program, you must be in the C:\Bookstore directory, use the dot character as the separator character:
java bookstore.Bookstore
Note that the preferred practice is to have no classes in the default package.
since the package has no name, there is no way to access it or any of its classes from any other package! since no other class needs to reference the main class, for now we will leave that in the default package.
Briefly:
the import statement enables you to use classes not in the default set (in this case the input-related classes) - the API documentation lists the package for each class the raw input class System.in is filtered using an InputStreamReader, which allows it to recognize input as text characters (the basic InputStream is plugged into a more complex object that does additional processing) then, the resulting InputStreamReader is plugged into a BufferedReader that buffers keyboard input until it recognizes the Enter keystroke lines can now be read using readLine(), and characters can be read using read() (note that they are read as integers, thus the typecast) a sequence of digits can be parsed using a static method of the Integer class since the whole input and parsing process is error-prone, we will avoid issues by having main throw an exception (much more on exceptions later)
The following class, KeyboardReader.java, can be used to read from the keyboard:
this comes at the expense of flexibility once created, a String object is immutable, that is, its contents cannot be changed methods like toUpperCase() that seem like they would change the contents actually return a brand-new String object with the new contents
they are essentially the same as far as available methods, but StringBuilder is not safe for multithreaded applications while StringBuffer is they are useful for building a long string from multiple pieces, or for text-editing applications among the useful methods are: o append(String s) and other forms accepting various primitive data types and a form that accepts another StringBuffer object o insert(int position, String s) to insert text at (in front of) the specified position; again, various forms for different types of data o delete(int start, int end) to delete characters from the start position up to but not including the end position o toString() will convert the contents of the object to a String object note that the modifying methods listed above modify the contents of the object, but also return a this reference, (a reference to the same object) - this enables chaining of method calls:
StringBuffer sb = new StringBuffer(); sb.append("Hello").append(" World"); System.out.println(sb.toString());
Javadoc Comments
A javadoc comment is a block comment beginning with /**, and ending with */
they may be used before any documentable item: (classes, fields, constructors, and methods - if used in other places they will be ignored by the documentation engine ) use them to provide descriptions of the item many HTML tags are valid within the comment - in particular, formatting tags like <em> and <code> are often used, as well as lists there are a number of special block tags that begin with @, such as: o @param documents a method or constructor parameter o @return documents a return value o {@link BookWithJavadoc} creates a hyperlink to the specified class page
Syntax
javadoc options filelist
-d destinationdirectory to produce the output in a specific directory, which need not already exist (default is current directory) options for access levels to document (each option generates documentation for that level and every more accessible level - e.g., protected documents public, package, and protected elements) o -private o -package o -protected o -public
The file list can use file names, package names, wildcards, like *.java (separate multiple elements with spaces) The following command places the output in a subdirectory docs of the current directory, and documents the "default package" and the employees package (use this in the upcoming exercise)
javadoc -d docs -private employees *.java
/** * The title of the book */ private String title; /** * Creates a book instance. It is expected that the value will * be non-negative; a negative value will be rejected. * @param itemCode the book's item code * @param title the title of the book */ public BookWithJavadoc(int itemCode, String title) { setItemCode(itemCode); setTitle(title); } /** * Creates a book instance, The item code willl be set to 0. * @param title the title of the book */ public BookWithJavadoc(String title) { setItemCode(0); setTitle(title); } /** * Retrieves the item code for the book. * @return the book's item code */ public int getItemCode() { return itemCode; } /** * Sets the item code for the book. It is expected that the value will * be non-negative; a negative value will be rejected. * @param itemCode the book's item code */ public void setItemCode (int itemCode) { if (itemCode > 0) this.itemCode = itemCode; } /** * Retrieves the title of the book. * @return the title of the book */ public String getTitle() { return title; } /** * Sets the title of the book. * @param title the title of the book */ public void setTitle (String title) { this.title = title;
Code Explanation
Even though some of the documentation will often be trivial, parameters and return values should always be documented. Any restrictions on parameter values, such as the nonnegative parameters, should be mentioned
Code Explanation
Note the use of the {@link} tag, since nothing else (parameter or return types) would mention the BookWithJavadoc class otherwise
fields methods constructors public and private access overloading the this reference packages javadoc comments
Boolean-Valued Expressions
Java has a data type called boolean
possible values are true or false can be operated on with logical or bitwise operators, but cannot be treated as a 0 or 1 mathematically can be specified as a parameter type or return value for a method a boolean value will print as true or false
simple comparisons, such as greater than, equal to, etc. values returned from functions complex combinations of simpler conditions
branching to another section of the program under specified conditions repeating loops of the same section of code
Comparison Operators
This chart shows the comparison operators and the types of data they can be applied to Operator boolean == != > < >= <= Purpose (Operation Performed) numeric primitives and char is equal to (note the two equals signs!) is not equal to is greater than is less than is greater than or equal to is less than or equal to Types of Data objects X X XX XX X X X X
note that it is unwise to use == or != with floating-point data types, as they can be imprecise
Comparing Objects
The operators == and != test if two references point to exactly the same object in memory they test that the numeric values of the two references are the same The equals(Object o) method compares the contents of two objects to see if they are the same (you can override this method for your classes to perform any test you want)
a > b will evaluate to false a < b will evaluate to true a >= b will evaluate to false a <= b will evaluate to true
String s = "Hello"; String r = "Hel"; String t = r + "lo";
s == t will evaluate to false s != t will evaluate to true (they are not the same object - they are two different objects that have the same contents) s.equals(t) will evaluate to true
String s = "Hello"; String t = s;
s == t will evaluate to true s != t will evaluate to false (they are the same object) s.equals(t) will evaluate to true Note: Java will intern a literal String that is used more than once in your code; that is, it will use the same location for all occurrences of that String
String s = "Hello"; String t = "Hello";
s == t will evaluate to true, because the String object storing "Hello" is stored only once, and both s and t reference that location s != t will evaluate to false (they are the same object) s.equals(t) will evaluate to true
there are also bitwise operators for AND, OR and bitwise inversion (changing all 1 bits to 0, and vice versa) since a boolean is stored as one bit, the bitwise AND and OR operators will give the same logical result, but will be applied differently (see below) for some reason, the bitwise NOT cannot be applied to a boolean value Bitwise
Logical
Examples:
Code Testing if a value falls within a range Effect
( ( a >= 0 ) && (a <= 10 is true if a is falls between 0 and 10; it must satisfy both conditions ))
Testing if a value falls outside a range
is true if a falls outside the range 0 to 10; it may be either below or above that range ( !( ( a >= 0 ) && (a <= inverts the test for a between 0 and 10; so a must be outside the range instead of inside it 10) ) ) ( ( a < 0 ) || (a > 10 ) ) The && and || operations are called short-circuiting, because if the first condition determines the final outcome, the second condition is not evaluated
to force both conditions to be evaluated, use & and | for AND and OR, respectively
Simple Branching
if Statement
Syntax
if (condition) statement;
or
Syntax
if (condition) { zero to many statements; }
causes "one thing" to occur when a specified condition is met the one thing may be a single statement or a block of statements in curly braces the remainder of the code (following the if and the statement or block it owns) is then executed regardless of the result of the condition.
The conditional expression is placed within parentheses The following flowchart shows the path of execution:
if Statement Examples
Absolute Value If we needed the absolute value of a number (a number that would always be positive):
Random Selection
Task: write a brief program which generates a random number between 0 and 1. Print out that the value is in the low, middle, or high third of that range (Math.random() will produce a double value from 0.0 up to but not including 1.0).
although it is a bit inefficient, just do three separate tests: (note that Math.random() will produce a number greater than or equal to 0.0 and less than 1.0)
Write a program called Game that will ask the user to guess a number, and compare their guess to a stored integer value between 1 and 100.
1. Use a property called answer to store the expected answer 2. For now, just hard-code the stored value, we will create a random value later (your code will be easier to debug if you know the correct answer) 3. Create a method called play() that holds the logic for the guessing 4. Create a main method, have it create a new instance of Game and call play() 5. Use the KeyboardReader class to ask for a number between 1 and 100, read the result, and tell the user if they are too low, correct, or too high Where is the solution?
3. Test your program to see what happens with negative input values 4. The code using Employee should avoiding sending it bad data, so also change main to check for pay rate and department values (print an error message for any negative entry, ane replace it with a value of 0 - later we will find a way to ask the user for a new value instead) Where is the solution?
does "one thing" if a condition is true, and a different thing if it is false it is never the case that both things are done the "one thing" may be a single statement or a block of statements in curly braces a statement executed in a branch may be any statement, including another if or if ... else statement.
This program tells you that you are a winner on average once out of every four tries:
the else clause can contain any type of statement, including another if or if ... else you can test individual values or ranges of values once an if condition is true, the rest of the branches will be skipped you could also use a sequence of if statements without the else clauses (but this doesn't by itself force the branches to be mutually exclusive)
note that we only need one test for the middle value - if we reach that point in the code, d must be greater than 1.0/3.0 similarly, we do not any test at all for the high third the original version worked because there was no chance that more than one message would print - that approach is slightly less efficient because all three tests will always be made, where in the if ... else version comparing stops once a match has been made.
Duration: 15 to 20 minutes. 1. Revise your number guessing program to use if . . . else logic (you can test for too low and too high, and put the message for correct in the final else branch) 2. Once you have done that, here is a way to generate a random answer between 1 and 100: 1. at the top:
import java.util.*;
4. the nextInt(int n) method generates a number greater than or equal to 0 and less than n, so r.nextInt(100) would range from 0 through 99; we need to add 1 to raise both ends of the range 5. you might want to print the expected correct answer to aid debugging
Note that until we cover looping, there will be no way to truly "play" the game, since we have no way to preserve the value between runs
Where is the solution?
a switch expression (usually a variable) is compared against a number of possible values used when the options are each a single, constant, value that is exactly comparable (called a case) the switch expression must be a byte, char, short, or int cases may only be byte, char, short, or int values, in addition, their magnitude must be within the range of the switch expression data type cannot be used with floating-point datatypes or long cannot compare an option that is a range of values, unless it can be stated as a list of possible values, each treated as a separate case cases are listed under the switch control statement, within curly braces, using the case keyword once a match is found, all executable statements below that point are executed, including those belonging to later cases - this allows stacking of multiple cases that use the same code the break; statement is used to jump out of the switch block, thus skipping executable steps that are not desired the default case keyword catches all cases not matched above note that, technically speaking, the cases are labeled lines; the switch jumps to the first label whose value matches the switch expression
Usage
Syntax
switch ( expression ) { case constant1: statements; break; case constant2: statements; break; . . . case constant3: case constant4MeansTheSameAs3: statements; break; . . . [default: statements;] }
Points to note:
stacking of cases for uppercase and lowercase letters allows both possibilities break; statements used to separate code for different cases default: clause used to catch all other cases not explicitly handled
Another example - taking advantage of the "fall-though" behavior without a break statement
What if we want to offer gamers multiple levels of difficulty in our game? We could make the range multiplier a property of the Game class, and set a value into it with a constructor, after asking the user what level they'd like to play.
1. Add a range property to the Game class (an int) 2. Add a new constuctor that accepts a level parameter; use a char 3. In the new constructor, create another new KeyboardReader (we will come up with a better solution later, where both main and play can share one KeyboardReader) 4. use a switch to process the incoming level: o uppercase or lowercase B means Beginner, set the range to 10 o I means Intermediate, set the range to 100 o A means Advanced, set the range to 1000
any other value results in beginner - after all, if they can't answer a simple question correctly, how could we expect them to handle a higher level game? o you could put the default option stacked with the 'B' cases to accomplish this o better yet, make it the first of that group, so that you can print an error message and then fall through to the 'B' logic 5. Modify the default constructor to call this new constructor, passing 'I' for intermediate 6. In the main method, ask the user for the level and call the new constructor with their response 7. Use range as the parameter when you call the Random object's nextInt method Where is the solution?
Comparing Objects
When comparing two objects, the == operator compares the references, to see if they are the same object (i.e., occupying the same spot in memory)
and != tests to see if they are two different objects (even if they happen to have the same internal values)
The Object class defines an equals(Object) method intended to compare the contents of the objects
the code written in the Object class simply compares the references using == this method is overridden for most API classes to do an appropriate comparison for example, with String objects, the method compares the actual characters up to the end of the string for classes you create, you would override this method to do whatever comparisons you deem appropriate
Code Explanation
The equals method compares another object to this object. This example is necessarily somewhat complicated. It involves a few concepts we haven't covered yet, including inheritance. Because the equals method inherited from Object takes a parameter which is an Object, we need to keep that that type for the parameter (technically, we don't need to do it by the rules of Java inheritance, but because other tools in the API are coded to pass an Object to this method). But, that means that someone could call this method and pass in something else, like a String. So, the first thing we need to do is test that the parameter was actually a Rectangle. If so, we can work with it - if not, there is no way it could be equal, so we return false. We will cover instanceof later, but, for now, we can assume it does what it implies - test that the object we received was an instance of Rectangle. Even after that test, in order to treat it as a Rectangle, we need to do a typecast to explicitly store it into a Rectangle variable (and again, we will cover object typecasting later). Once we have it in a Rectangle variable, we can check its height and width properties. As an aside, note that private data in one instance of a class is visible to other instances of the same class - it is only other classes that cannot see the private elements.
Code Explanation
Since all the important work is done in Rectangle, all we need to do here is instantiate two and compare them using both == and the equals method to see the differing results. The output should be:
you can preset the message assuming that they are incorrect, then change it if they are correct
Conditional Expression
Java uses the same conditional expression as C and C++
Syntax
condition ? expressionIfTrue : expressionIfFalse
This performs a conditional test in an expression, resulting in the first value if the condition is true, the second if the condition is false Note: due to operator precedence issues, it is often best to enclose the entire expression in parentheses Example
Note that the parentheses around the test are not necessary by the operator precedence rules, but may help make the code clearer The parentheses around the entire conditional expression are necessary; without them, precedence rules would concatenate the boolean result onto the initial string, and then the ? operator would be flagged as an error, since the value to its left would not be a boolean.
or
Syntax
while (condition){ block of statements }
the loop continues as long as the expression evaluates to true the condition is evaluated before the start of each pass it is possible that the body of the loop never executes at all (if the condition is false the first time)
or
Syntax
do { block of statements } while (condition);
the condition is evaluated after the end of each pass the body of the loop will always execute at least once, even if the condition is false the first time
for Loops
A for loop uses a counter to progress through a series of values
a value is initialized, tested each time through, and then modified (usually incremented) at the end of each pass, before it is tested again the for loop does not do anything that cannot be done with a while loop, but it puts everything that controls the looping at the top of the block
Syntax
for (initialize; condition; change) statement;
or
Syntax
for (initialize; condition; change) { block of statements }
for loops often use a variable with block-level scope (existing only for the duration of the loop), created in the control portion of the loop
int j; for (j = 0; j < 12; j++ ) System.out.print("j = " + j); for (int j = 0; j < 12; j++ ) System.out.print("j = " + j);
A for loop may use multiple control variables by using the sequence operator, the comma ( ,)
for (int j = 0, k = 12; j <= 12; j++, k-- )
Note: if you use a block-scope variable (such as above) for the first counter, the additional ones will be block scope as well, and also will be the same type of data - i.e., the variable k above also exists only for the duration of the block. There is no way to declare two counters of different types at block-level scope..
ForEach Loops
Java 5 introduced a new type of loop, the for-each loop. When you have an array or collection class instance, you can loop through it using a simplified syntax
Syntax
for (type variable : arrayOrCollection) { body of loop }
The looping variable is not a counter - it will contain each element of the array or collection in turn (the actual value, not an index to it, so its type should be the same as the type of items in the array or collection). You can read the : character as if it was the word "from". We will cover this type of loop in more depth in the Arrays section. For some reason, the looping variable must be declared within the parentheses controlling the loop - you cannot use a preexisting variable.
System.out.println("For loop that declares a counter:"); for (int j = 0; j < 12; j++) System.out.print(" " + j); System.out.println(); System.out.println("ForEach loop:"); String[] names = { "Jane", "John", "Bill" }; for (String oneName : names) System.out.println(oneName.toUpperCase()); } }
execution jumps to the first statement following the loop the following example prints random digits until a random value is less than 0.1
Code Explanation
This code loops, generating and printing a random number for each iteration. If the number is less than 0.1, we break out before printing it.
This code avoids the break, by creating and testing the random number in the control part of the loop. As part of the iteration condition, if the number is less than 0.1, the loop simply ends "normally".
Continuing a Loop
If you need to stop the current iteration of the loop, but continue the looping process, you can use the continue statement
normally based on a condition of some sort execution skips to the end of this pass, but continues looping it is usually a better practice to reverse the logic of the condition, and place the remainder of the loop under control of the if statement
count++; System.out.println("Number " + count + " is " + num); } while (count < 10); System.out.println("Thank you"); } /* // a better way public static void main(String[] args) throws IOException { int count = 0; do { int num = KeyboardReader.getPromptedInt("Enter an integer: "); if (num >= 0) { count++; System.out.println("Number " + count + " is " + num); } } while (count < 10); System.out.println("Thank you"); } */ }
A better way to handle the loop is shown in the commented out version of main - try removing the comment marks and commenting out the original method But, continue is easier to use in nested loops, because you can label the level that will be continued
Try the following example as is, then reverse the commenting on the break lines
Using CLASSPATH
Java has a CLASSPATH concept that enables you to specify multiple locations for .class files, at both compile-time and runtime.
by default, Java uses rt.jar in the current Java installation's lib directory, and assumes that the classpath is the current directory (the working directory in an IDE) if you create a classpath, the default one disappears, so any classpath that you create must include the current directory using a period (.) character
To use an external library, you would need to create a classpath in one of two ways:
1. you can create a system or user environment variable, with multiple directories and/or .jar files, separated by the same delimiter used by your PATH (a semicolon in Windows) 2. you could use the -classpath option in java and javac (-cp is a shorthand version of that)
Here is an example of a pair of commands to compile and run using an external library stored in a jar file. Note that we need the jar file at both compile-time and runtime. The -cp option in both commands replaces the system classpath with one specifically for that command.
javac -cp c:\Webucator\Java102\ClassFiles\utilities.jar;. *.java java -cp c:\Webucator\Java102\ClassFiles\utilities.jar;. Payroll
Many Integrated Developments (IDEs) have a means to specify project properties; usually an item like "Build Path" will have options to specify external jar files (as well as choose from various libraries supplied with the environment).
If you wish to create your own library of useful classes, you can bundle one or more classes and/or directories of classes in a jar file
the root level of the file structure should match the root of the package structure, for example, to put KeyboardReader in a jar file, we would want to start at the directory where util is visible, and jar that
The following command will create a jar file called utilities.jar for all files in the util package (just KeyboardReader, in this case)
jar -cvf utilities.jar util\*.class
the options are create, verbose, and use a list of files supplied at the end of the command
The destination directory can be a relative path from the current directory, or an absolute path. It must already exist, but an subdirectories necessary for package structures will be created.
Arrays
In this lesson of the Java tutorial, you will learn... 1. 2. 3. 4. Understand how arrays are implemented in Java Declare, instantiate, populate, and use arrays of primitives Use arrays of objects Use multi-dimensional arrays
Arrays
an array variable does not actually store the array - it is a reference variable that points to an array object declaring the array variable does not create an array object instance; it merely creates the reference variable - the array object must be instantiated separately once instantiated, the array object contains a block of memory locations for the individual elements if the individual elements are not explicitly initialized, they will be set to zero arrays can be created with a size that is determined dynamically (but once created, the size is fixed)
Declare an array variable by specifying the type of data to be stored, followed by square brackets []
Syntax
dataType[] variableName;
which you can read as "String array names" - the array holds String references
You may also put the brackets after the variable name (as in C/C++), but that is less clearly related to how Java actually works
int nums[]; // not recommended, but legal
Instantiating Arrays
Instantiate an array object using new, the data type, and an array size in square brackets
int[] nums; nums = new int[10];
the second line constructs a new array object with 10 integer elements, all initialized to 0, and stores the reference into nums
in the above example, names.length would be 3 the property is fixed (i.e., it is read-only)
the original ten-element array is no longer referenced by nums, since it now points to the new, larger array
Initializing Arrays
An array can be initialized when it is created
or
String[] names = new String[] {"Joe", "Jane", "Herkimer" };
this automatically creates an array of length 3, because there were 3 items supplied
If a new array is being assigned to an existing variable, you cannot use the shorter variant, you must use the new keyword and the data type:
the index is the element number, placed within brackets elements are numbered from 0 to one less than the specified size
The compiler does no checking to ensure that you stay within the bounds of the array
but the JVM does check at runtime - if you try to exceed the bounds of the array, an exception will occur
you might create a zero-length array as the return value from a method typed as returning an array, when there are no items to return (as opposed to returning null)
Array Variables
The array as a whole can be referenced by the array name without the brackets, for example, as a parameter to or return value from a function
names[0] = "Joe"; names[1] = "Jane"; names[2] = "Herkimer"; printArray(names); } public static void printArray(String[] data) { for (int i = 0; i < data.length; i++) { System.out.println(data[i].toUpperCase()); } } }
Code Explanation
The array names is passed to printArray, where it is received as data. Note also the syntax to access a method directly for an array element: data[i].toUpperCase() Since an array reference is a variable, it can be made to refer to a different array at some point in time
String[] names = new String[3]; names[0] = "Joe"; names[1] = "Jane"; names[2] = "Herkimer"; printArray(names); names = new String[2]; names[0] = "Rudolf"; names[1] = "Ingrid"; printArray(names);
Copying Arrays
You can use System.arraycopy to copy an array into another
you might do this to expand an array by creating a larger one and copying the contents of the smaller one into it (but any references to the original array will need to be changed to point to the new array) the declaration is:
public static void arraycopy( Object src, int srcPos, Object dest, int destPos, int length)
System.arraycopy(nums, 0, biggerNums, nums.length, nums.length); for (int i = 0; i < biggerNums.length; i++) System.out.println(biggerNums[i]); } }
Code Explanation 1. The first arraycopy line copys from nums into the first half of biggerNums. The number of items copied is determined by nums.length
System.arraycopy(nums, 0, biggerNums, 0, nums.length);
2. The second arraycopy line again copys from nums, but now into the second half of biggerNums. The starting location for the "paste" is nums.length, since that is where we left off the first time. And the number of items copied is again determined by nums.length
3. System.arraycopy(nums, 5, biggerNums, nums.length, nums.length);
Arrays of Objects
If an array contains objects, those objects' properties and methods may be accessed
the notation uses the array variable name, the index in brackets, a dot, and the property or method
the collection of values can be any array or an instance of one of the Java Collections classes (to be discussed later) note that the looping variable must be declared in the parentheses that create the loop you cannot use a preexisting variable as the loop variable
the looping variable will represent each item from the collection or array in turn
Syntax
for (dataType loopVariable : collectionOfSameType) code using loopVariable;
Multi-Dimensional Arrays
Arrays may have more than one dimension, for such things as:
a graphic image that is x pixels across and y pixels vertically weather information modeled in a 3-dimensional space, with measurements for these axes: North/South, East/West, and altitude
Arrays are objects, and, like other objects, declaring a variable does not instantiate the array - that must be done separately. To instantiate a multidimensional array:
Syntax
arrayName = new datatype[size1][size2] ... [sizeN];
the most significant dimension is listed first; the least significant dimension listed last
could be used to declare an array to store an image that is 640 pixels across and 480 pixels down - in a graphic the image data is stored sequentially across each row; each row is a 640 pixel block; there are 480 of these blocks in our image
this might be used for an image where the data is stored in three layers, each of which is an entire 480 by 640 array.
int[][] nums;
could be thought of as an array of integer arrays, as if it were written as (note that this is not legal syntax):
(int[])[] nums;
In Java, a two-dimensional array is actually a single array of array reference variables, each of which points to a single dimensional array To extend the example above:
int[][] nums = new int[3][6];
Note that it is possible to replace any of the one-dimensional elements with a different one, or that the second-dimension arrays each have a different length - the following line would replace one of the arrays with another of a different length
there is a loop that processes each row (the first, or most significant, dimension of the array, each element of which is an array of characters) within that loop, another loop prints each character without ending the line then, when the inner loop is done, a newline is printed
{ { { { { };
',' ',' ','|',' ',' ',' ','0','-','+','-','0',' ',' ',' ','|',' ',' ',' ',' ',' ','0',' ',' ',' ',' ',' ',' ',' ',' ','
}, }, }, }, }
for (int row = 0; row < imgData.length ; row++ ) { for (int col = 0; col < imgData[row].length; col++ ) { System.out.print(imgData[row][col]); } System.out.println(); } } }
Because multi-dimensional arrays are implemented as arrays of array references, it is possible to partially instantiate an array:
int[][] nums = new int[3][];
This creates nums as a two-dimensional array (better viewed in this case as an array of array references), and creates an array holding three null references to integer arrays
We would like to keep track of our employees' dependents; the plan is to have the Employee class contain an array of objects, each of which represents one dependent The class representing a dependent should contain a reference to the employee that it belongs to, in case we need to look up any employee-related information from a dependent reference
1. Create a new class (in the employees package) called Dependent, with String properties for first and last names, and property called dependentOf, whose type is Employee 2. It should have a constructor that accepts values for all three properties - give the constructor package access instead of public 3. It should have set and get methods for the name properties, and only a get method for the employee they are a dependent of 4. Add a property called dependents to Employee that is an array of Dependent objects, and instantiate a five-element array o while this isn't the best practice, there isn't a much better solution, since the fundamental problem is that an array isn't really a good idea for a set of items with no fixed size - a collection class would be better o it would, however, be an improvement to have a method like createDependentArray(int size) that could at least provide each employee with an individually sized array (which still couldn't be expanded) o feel free to implement this ehnancement if you have time 5. It is generally considerered a risky practice to create get and set methods for an array property - it exposes too much of the inner workings of the class to outside code (since it would enable wholesale replacement of the array or of the array's contents). Instead, we can control the array through properties and methods in the Employee class. To start, add an int numDependents property to Employee. 6. Create an addDependent(String firstName, String lastName) method that instantiates a dependent using the provided names and the this reference for the third parameter to the Dependent constructor (the Employee reference) 7. The addDependent method should then put the new dependent at the numDependents location in the array, and increment numDependents, but only if numDependents is less than the length of the array 8. Add the method listed below to the Employee class (you can copy it from the solution):
9. public String listDependents() { 10. StringBuffer temp = new StringBuffer(); 11. String newline = System.getProperty("line.separator"); 12. if (newline == null) newline = "\n"; 13. for (int i = 0; i < dependents.length; i++) { 14. temp.append(dependents[i].getFirstName()); 15. temp.append(" "); 16. temp.append(dependents[i].getLastName()); 17. temp.append(newline); 18. } 19. return temp.toString(); }
20. In your data-populating loop, add a question about how many dependents 21. Use a loop to get the names and add each dependent to the employee 22. When you print out the Employee information, also print out the result of calling listDependents Where is the solution?
Code Explanation
Neither an implicit or explicit typecast can be performed. With a single int i, the copy of it that is given to d can be expanded to a double. But, with the int[] inums, the value that would be given to dnums is just a copy of the reference to inums, so there is no way that each of the individual elements can be expanded to double. The next chapter will discuss typecasting from arrays of one type of object to another.
Arrays Conclusion
In this lesson of the Java tutorial you have learned how to declare, instantiate and work with arrays of primitives and objects.
Inheritance
In this lesson of the Java tutorial, you will learn... 1. 2. 3. 4. Understand the OOP concept of inheritance Examine the role of inheritance in a program Declare and use Java classes that extend existing classes Understand the concept and role of polymorphism in Java
Inheritance
Inheritance creates a new class definition by building upon an existing definition (you extend the original class) The new class can, in turn, can serve as the basis for another class definition
all Java objects use inheritance every Java object can trace back up the inheritance tree to the generic class Object
The keyword extends is used to base a new class upon an existing class Several pairs of terms are used to discuss class relationships (these are not keywords)
note that traditionally the arrows point from the inheriting class to the base class, and the base class is drawn at the top - in the Unified Modeling Language (UML) the arrows point from a class to another class that it depends upon (and the derived class depends upon the base class for its inherited code) the parent class/child class terms are not recommended, since parent and child is more commonly used for ownership relationships (like a GUI window is a parent to the components placed in it)
A derived class instance may be used in any place a base class instance would work - as a variable, a return value, or parameter to a method Inheritance is used for a number of reasons (some of the following overlap)
to model real-world hierarchies to have a set of pluggable items with the same "look and feel," but different internal workings to allow customization of a basic set of features when a class has been distributed and enhancements would change the way existing methods work (breaking existing code using the class) to provide a "common point of maintenance"
When extending a class, you can add new properties and methods, and you can change the behavior of existing methods (which is called overriding the methods)
you can declare a method with the same signature and write new code for it you can declare a property again, but this does not replace the original property - it shadows it (the original property exists, but any use of that name in this class and its descendants refers to the memory location of the newly declared element)
Inheritance Examples
Say you were creating an arcade game, with a number of different types of beings that might appear - wizards, trolls, ogres, princesses (or princes), frogs, etc.
all of these entities would have some things in common, such as a name, movement, ability to add/subtract from the player's energy - this could be coded in a base class Entity for entities that can be chosen and controlled by a player (as opposed to those that merely appear during the course of the game but can't be chosen as a character) a new class Playable could extend Entity by adding the control features then, each individual type of entity would have its own special characteristics - those that can be played would extend Playable, the rest would simply extend Entity you could then create an array that stored Entity objects, and fill it with randomly created objects of the specific classes for example, your code could generate a random number between 0 and 1; if it is between 0.0 and 0.2, create a Wizard, 0.2 - 0.4 a Prince, etc.
The Java API is a set of classes that make extensive use of inheritance
one of the classes used in the GUI is Window - its family tree looks like:
they all share basic characteristics such as getting paid (albeit via different algorithms), withholding, having to accumulate year-to-date numbers for numerous categories but they have different handling regarding payment calculations, benefits, dependents, etc. exempt employees get a monthly salary, while nonexempt get a wage * hours, contract employees are handled similarly to nonexempt, but cannot have dependents
Also, we have already seen some duplication of effort in that our dependents store some of the same information as employees (first and last names)
they use this information for the same purposes, so it might make sense to pull that common information into a base class
Note that a scheme with ContractEmployee extending NonexemptEmployee might also be a reasonable approach
lets assume that the Entity class defines the properties name, energy, and position, and methods moveTo() and changeEnergy() the Playable class adds a property playerID the Wizard class adds a spells property (an array of spells they can cast) and a castSpell() method
Any Wizard object contains all the elements inside its box, include those of the base classes
so, for example, the complete set of properties in a Wizard object is: o name o energy o position o playerID o spells a Wizard reference to a Wizard object has access to any public elements from any class in the inheritance chain from Object to Wizard code inside the Wizard class has access to all elements of the base classes (except those defined as private in the base class - those are present, but not directly accessible) a more complete description of access levels is coming up in a few pages
Note: although it appears that a base class object is physically located inside the derived class instance, it is not actually implemented that way
Polymorphism
the compiler knows that all the features of the base class were inherited, so they are still there to work in the derived class (keeping in mind that they may have been changed)
This demonstrates what is known as an IsA relationship - a derived class object Is A base class instance as well
it is an example of polymorphism - that one reference can store several different types of objects for example, in the arcade game example, for any character that is used in the game, an Entity reference variable could be used, so that at runtime, any subclass can be instantiated to store in that variable
Entity shrek = new Ogre(); Entity merlin = new Wizard();
When this is done, however, the only elements immediately available through the reference are those know to exist; that is, those elements defined in the reference type object
the compiler decides what to allow you to do with the variable based upon the type declared for the variable merlin.moveTo() would be legal, since that element is guaranteed to be there merlin.castSpell() would not be legal, since the definition of Entity does not include it, even though the actual object referenced by w does have that capability the following example gives a hint as to why this is the case:
Entity x; if (Math.random() < 0.5) x = new Wizard(); else x = new Troll();
there is no way the compiler could determine what type of object would actually be created
the variables names above, shrek, merlin, and charles, are probably not good choices: presumably we know shrek is an ogre, and always will be, so the type might as well be Ogre (unless, of course, he could transmogrify into something else during the game ...)
In this manner, what you could consider the most advanced (or most derived) version of the method will run, even if you had a base class reference. So, for our arcade game, an Entity reference could hold a Wizard, and when the move method is called, the Wizard version of move will run. An interesting aspect of dynamic method invocation is that it occurs even if the method is called from base class code. If, for example:
the Entity class move method called its own toString method the Ogre class didn't override move, but did override toString for an Ogre stored in an Entity variable, the move method was called
The Entity version of move would run, but its call to toString would invoke the toString method from Ogre!
if you do not extend any class, Java assumes you are extending Object by default
Your new class can use the properties and methods contained in the original class (subject to the note coming up in a few pages about access keywords), add new data properties and methods, or replace properties or methods A derived class object may be stored in a base class reference variable without any special treatment - the reverse is not true, but can be forced Java doesn't allow multiple inheritance, where one class inherits from two or more classes
it does have a concept called an interface, which defines a set of method names a class may implement an interface, defining those methods in addition to whatever other methods are in the class this allows for several otherwise unrelated classes to have the same set of method names available, and to be treated as the same type of object for that limited set of methods
When a derived class is created, an object of the new class will in effect contain a complete object of the base class within it The following maps out the relation between the derived class and the base class (note that the diagrams show the apparent memory allocation, in a real implementation the base class memory block is not inside the derived class block)
public class MyBase { public int x; public void show() { System.out.println("x =" + x); }
class MyDerived extends MyBase { public int y; public void show() { System.out.println("x = " + x); System.out.println("y = " + y); } }
Since everything in MyBase is public, code in the MyDerived class has free access to the x value from the MyBase object inside it, as well as y and show() from itself
the show() method from MyBase is also available, but only within MyDerived class code (but some work is required to get it, since it is hidden by the show() method added with MyDerived) - code in other classes cannot invoke the MyBase version of show() at all
When inheritance is used to create a new (derived) class from an existing (base) class, everything in the base class is also in the derived class
it may not be accessible, however - the access in the derived class depends on the access in the base class: base class access accessibility in derived class public protected inaccessible
Note that private elements become inaccessible to the derived class - this does not mean that they disappear, or that that there is no way to affect their values, just that they can't be referenced by name in code within the derived class Also note that a class can extend a class from a different package
constructors are "not inherited" in a sense, this is a moot point, since they would have a different name in the new class, and can't be called by name under any circumstances, so, for example, when one calls new Integer(int i) they shouldn't expect a constructor named Object(int i) to run
Within a derived class constructor, however, you can use super( parameterList ) to call a base class constructor
it must be done as the first line of a constructor therefore, you can't use both this() and super() in the same constructor function if you do not explicitly invoke a form of super-constructor, then super() (the form that takes no parameters) will run and for the superclass, its constructor will either explicitly or implicitly run a constructor for its superclass so, when an instance is created, one constructor will run at every level of the inheritance chain, all the way from Object up to the current class
Code Explanation
a MyDerived object has two constructors available, as well as both the getX and getY methods and the show method both MyDerived constructors call the super constructor to handle storage of x the show method in the derived class overrides the base class version x from the base class is not available in the derived class, since it is private in MyBase, so the show method in MyDerived must call getX() to obtain the value
the new method overrides (and hides) the original method you can still call the base class method from within the derived class if necessary, by adding the super keyword and a dot in front of the method name the base class version of the method is not available to outside code you can view the super term as providing a reference to the base class object buried inside the derived class you cannot do super.super. to back up two levels
you cannot change the return type when overriding a method, since this would make polymorphism impossible
One base class constructor will always run when instantiating a new derived class object
if you do not explicitly call a base class constructor, the no-arguments base constructor will be automatically run, without the need to call it as super() but if you do explicitly call a base class constructor, the no-arguments base constructor will not be automatically run the no-arguments (or no-args for short) constructor is often called the default constructor, since it the one that will run by default (and also because you are given it by default if you write no constructors)
Code Explanation
Each constructor prints a message so that we can follow the flow of execution. Note that using new Violet() causes Purple() to run, and that new Violet(4) also causes Purple() to run. If your base class has constructors, but no no-arguments constructor, then the derived class must call one of the existing constructors with super(args), since there will be no default constructor in the base class. If the base class has a no-arguments constructor that is private, it will be there, but not be available, since private elements are hidden from the derived class. So, again, you must explicitly call an available form of base class constructor, rather than relying on the default
try the above code with the Purple() constructor commented out or marked as private
When the process has completed, the expression that created the instance evaluates to the address of the block for the last unit in the chain.
private String lastName; public Person() { } public Person(String firstName, String lastName) { setFirstName(firstName); setLastName(lastName); } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getFullName() { return firstName + " " + lastName; } }
Code Explanation
This class includes the name properties and related set and get methods.
Code Explanation
Since this class extends Person, the name-related elements are already present, so we remove them from this code.
public String listDependents() { if (dependents == null) return ""; StringBuffer temp = new StringBuffer(); String newline = System.getProperty("line.separator"); if (newline == null) newline = "\n"; for (int i = 0; i < numDependents; i++) { temp.append(dependents[i].getFirstName()); temp.append(" "); temp.append(dependents[i].getLastName()); temp.append(newline); } return temp.toString(); } public String getPayInfo() { return "Employee " + id + " dept " + dept + " " + getFullName() + " paid " + payRate; } }
Code Explanation
The same changes that were made to Dependent can be made here. Note that since getPayInfo calls getFullName, which is now inherited and publicly accessible, that code did not need to change.
numDeps = kbr.getPromptedInt("How many dependents? "); for (int d = 0; d < numDeps; d++) { dfName = kbr.getPromptedString("Enter dependent first name: "); dlName = kbr.getPromptedString("Enter dependent last name: "); e.addDependent(dfName, dlName); } System.out.println(e.getPayInfo()); System.out.println(e.listDependents()); } }
Code Explanation
No changes need to be made to Payroll to take advantage of the addition of the inheritance hierarchy that we added - the only changes we made were for the sake of brevity. To revisit the sequence of events when instantiating a Dependent using the constructor that accepts the Employee and first and last names:
1. 2. 3. 4. 5. 6. memory for an Object is allocated any Object initializers would run the Object() constructor would run memory for a Person is allocated it there were any Person initializers, they would run the Person(String firstName, String lastName) constructor would run, because that was the version selected by the Dependent constructor we called 7. memory for a Dependent is allocated 8. it there were any Dependent initializers, they would run 9. the Dependent constructor we called would run
We wish to improve our payroll system to take account of the three different types of employees we actually have: exempt, non-exempt, and contract employees. Rather than use some sort of identifying code as a property, OOP makes use of inheritance to handle this need, since at runtime a type can be programmatically identified. Also, the solution code builds upon the Person base class from the preceding example. You can either copy the Person.java file into your working directory and edit Employee.java to match, or just copy the set of files from the Demos directory into a new working directory and use those.
1. Create three new classes: ExemptEmployee, NonexemptEmployee, and ContractEmployee that extend Employee (one possible approach is to copy the base class into new files and modify them)
2. In our company, exempt employees get a monthly salary, non-exempt an hourly rate that is multiplied by their hours, as do contract employees - revise the getPayInfo method to take this into account and also identify which type of employee it is (note that the payRate field will hold a monthly amount for exempt and an hourly amount for non-exempt and contractors, but these last two will need an additional field for their hours, plus methods to set and get the hours) 3. We need some way to handle the fact that contract employees do not have dependents for now, just override listDependents to do nothing for a contract employee, and also override the addDependent method to do nothing for a ContractEmployee o we can see here a problem with the hard-coded instantiation of the dependents array in Employee o a better approach might be to leave it as null, and add a method to create the array, which could accept a size at that time (we won't bother to do this, since the collections classes offer a much better way that we will implement later) 4. Add constructors as you see fit 5. Have the main program create and display the information for instances of each type of employee (for now, comment out the code that uses the Employee array and just hardcode one of each type of employee) Where is the solution?
if class MyDerived is derived from MyBase, then a reference to one can be typecast to the other
An upcast converts from a derived type to a base type, and will be done implicitly, because it is guaranteed that everything that could be used in the parent is also in the child class
Object o; String s = new String("Hello"); o = s;
A downcast converts from a parent type to a derived type, and must be done explicitly
Object o = new String("Hello"); String t; t = (String) o;
even though o came from a String, the compiler only recognizes it as an Object, since that is the type of data the variable is declared to hold
As a memory aid, if you draw your inheritance diagrams with the parent class on top, then an upcast moves up the page, while a downcast moves down the page
a downcast could fail at runtime because you might call a method that is not there, so the JVM checks when performing the cast in order to fail as soon as possible, rather than possibly having some additional steps execute between casting and using a method
Object o = new Integer(7); String t, u; // compiler will allow this, but it will fail at runtime t = (String) o; u = t.toUpperCase();
since t was not actually a String, this would fail with a runtime exception during the cast operation - at that point the runtime engine sees that it cannot make the conversion and fails
((MyBase) rv) casts rv to a MyDerived, for which the getY() method is run note the parentheses enclosing the inline typecast operation; this is because the dot operator is higher precedence than the typecast; without them we would be trying to run rv.getY() and typecast the result
you must explicitly downcast the references back to their original class in order to access their unique properties and methods if you have upcast, to store a derived class object with a base class reference, the compiler will not recognize the existence of derived class methods that were not in the base class the collection classes, such as Vector, are defined to store Objects, so that anything you store in them loses its identity
o o
you must downcast the reference back to the derived type in order to access those methods the introduction of generics in Java 1.5 provides a solution to this annoyance (more on this in the Collections chapter)
During execution, using a base class reference to call to a method that has been overridden in the derived class will result in the derived class version being used - this is called dynamic method invocation The following example prints the same way twice, even though two different types of variable are used to reference the object:
More on Overriding
Changing access levels on overridden methods
You can change the access level of a method when you override it, but only to make it more accessible
you can't restrict access any more than it was in the base class so, for example, you could take a method that was protected in the base class and make it public for example, if a method was public in the base class, the derived class may not override it with a method that has protected, private or package access
since a base class variable can reference a derived class object, the compiler will allow it to access something that was public in the base class if the derived class object actually referenced had changed the access level to private, then the element ought to be unavailable this logic could be applied to any restriction in access level, not just public to private
As a more specific example of why this is the case, imagine that ExemptEmployee overrode public String getPayInfo() with private String getPayInfo()
because Employee, the type on the variable e, says that getPayInfo is public but, now at runtime, it shouldn't be accessible, since it is supposed to be private in ExemptEmployee
Redefining properties
A property in a derived class may be redefined, with a different type and/or more restrictive access - when you do this you are creating a second property that hides the first; this is called shadowing instead of overriding
a new property is created that hides the existence of the original property since it actually a new property being created, the access level and even data type may be whatever you want - they do not have to be the same as the original property I dont know of any good reason to do this, but it is possible a strange thing happens when you use a base class reference to such a class where the property was accessible (for example, public) o the base class reference sees the base class version of the property!
the exact type of Entity would be unknown at compile time but during execution we would like to instantiate different types of Entity at random
Perhaps our code for Entity includes a method move() that moves it to a new location. Many of the entities move the same way, but perhaps some can fly, etc. We could write a generally useful form of move in the Entity class, but then override it as necessary in some of the classes derived from Entity.
public Playable(String name) { super(name); } public void move() { System.out.println("I am " + getName() + ". Here we go!"); } } class Ogre extends Entity { public Ogre(String name) { super(name); } } class Troll extends Entity { public Troll(String name) { super(name); } } class Princess extends Playable { public Princess(String name) { super(name); } public void move() { System.out.println("I am " + getName() + ". Watch as I and my court move!"); } } class Wizard extends Playable { public Wizard(String name) { super(name); } public void move() { System.out.println("I am " + getName() + ". Watch me translocate!"); } } public class EntityTest { public static void main(String[] args) { String[] names = { "Glogg", "Blort", "Gruff", "Gwendolyne", "Snow White", "Diana", "Merlin", "Houdini", "Charles", "George" }; for (int i = 0; i < 10; i++) { int r = (int) (Math.random() * 4); Entity e = null; switch (r) { case 0: e = new Ogre(names[i]); break; case 1: e = new Troll(names[i]); break; case 2: e = new Wizard(names[i]); break; case 3: e = new Princess(names[i]); break; } e.move(); } } }
The compiler allows the calls to the move() method because it is guaranteed to be present in any of the subclasses - since it was created in the base class
if not overridden in the derived class, then the base class version will be used if the method is overridden by the derived class, then the derived class version will be used
At runtime, the JVM searches for the method implementation, starting at the actual class of the instance, and moving up the inheritance hierarchy until it finds where the method was implemented, so the most derived version will run.
in the above example, perhaps wizards, ogres, trolls, etc. have their own special methods how would you know which method to call if you had an Entity reference that could hold any subclass at any time?
The instanceof operator is used in comparisons - it gives a boolean answer when used to compare an object reference with a class name
Syntax
referenceVariable instanceof ObjectType
it will yield true if the object is an instance of that class it will also give true if the object is a derived class of the one tested if the test yields true, then you can safely typecast to call a derived class method (you still need to typecast to call the method - the compiler doesn't care that you performed the test)
For example:
if (e[i] instanceof Wizard) ((Wizard) e[i]).castSpell();
every object has a getClass() method that returns a Class object that uniquely identifies each class every class has a class property that provides the same Class object as above; this object is the class as loaded into the JVM (technically, class isn't a property, but syntax-wise it is treated somewhat like a static property) with this method, a derived class object's class will compare as not equal to the base class
Code Explanation
Both upcasts and downcasts can be made. Because the arrays store references, the physical attributes, like the size, of each element remains the same regardless of what type of object the element references.
abstract
States that the item cannot be realized in the current class, but can be if the class is extended
Syntax
abstract [other modifiers] dataType name ...
for a class, it states that the class can't be instantiated (it serves merely as a base for inheritance) for a method, it states that the method is not implemented at this level the abstract keyword cannot be used in conjunction with final
abstract Classes
Used when a class is used as a common point of maintenance for subsequent classes, but either structurally doesn't contain enough to be instantiated, or conceptually doesn't exist as a real physical entity
public abstract class XYZ { ... }
we will make the Employee class abstract in the next exercise: while the concept of an employee exists, nobody in our payroll system would ever be just an employee , they would be exempt, non-exempt, or contract employees while you cannot instantiate an object from an abstract class, you can still create a reference variable whose type is that class
abstract Methods
The method cannot be used in the current class, but only in a inheriting class that overrides the method with code
public abstract String getPayInfo();
the method is not given a body, just a semicolon after the parentheses if a class has an abstract method, then the class must also be abstract you can extend a class with an abstract method without overriding the method with a concrete implementation, but then the class must be marked as abstract
final
Used to mark something that cannot be changed
Syntax
final Classes
The class cannot be extended
public final class XYZ { ... }
final Methods
The method cannot be overridden when the class is extended
public final void display() { ... }
final Properties
Marks the property as a constant
public static final int MAX = 100;
or
public final double randConstant;
then, in a constructor:
randConstant = Math.random();
note: String and the wrapper classes use this in two ways : o the class is final, so it cannot be extended o the internal property storing the data is final as well, but set by the constructor (this makes the instance immutable - the contents cannot be changed once set) in some cases, a declaration of final enables the compiler to optimize methods, since it doesn't have to leave any "hooks" in for potential future inheritance
Note that final and abstract cannot be used for the same element, since they have opposite effects.
1. Mark the Person and Employee classes as abstract 2. Make the getPayInfo() method abstract in Employee Where is the solution?
this method must be overridden, otherwise an exception will occur (the Object version of clone throws a CloneNotSupportedException) the issue is whether to perform a shallow copy or a deep copy - a shallow copy merely copies the same reference addresses, so that both the original object and the new object point to the same internal objects; a deep copy makes copies of all the internal objects (and then what if the internal objects contained references to objects )
if you don't override this method, you get the same result as if you used == (that is, the two references must point to the same object to compare as equal - two different objects with the same properties would compare as unequal) - that is how the method is written in the Object class you would override this method with whatever you need to perform a comparison
int hashCode() - returns an integer value used by collection objects that store elements using a hashtable
elements that compare as the same using the equals(Object) method should have the same hashcode
this method is called by a some elements in the Java API when the object is used in a situation that requires a String, for example, when you concatenate the object with an existing String, or send the object to System.out.println()
note that the call to toString is not made automatically as a typecast to a String - the only behavior built into the syntax of Java is string concatenation with the + sign (so one of the operands must already be a String); the code in println is explicitly written to call toString if you don't override this method, you will get a strange string including the full class name and the hashcode for the object
this method might never be called (the program may end without the object being collected)
There are also a several methods (wait, notify, and notifyAll) related to locking and unlocking an object in multithreaded situations
ObjectMethods om3 = new ObjectMethods (2, "Jane", 5); ObjectMethods om4 = (ObjectMethods)om3.clone(); System.out.println("Printing an object: " + om1); if (om1.equals(om2)) System.out.println("om1 equals(om2)"); if (om1.equals(om3)) System.out.println("om1 equals(om3)"); if (om1.equals("John")) System.out.println("om1 equals(\"John\")"); if (om3.equals(om4)) System.out.println("om3 equals(om4) which was cloned from om3"); System.out.println("object class is: " + om1.getClass()); } }
Code Explanation
The clone method returns Object rather than ObjectMethods, since that is how it was declared in the Object class, and you can't change the return type when overriding - thus the typecast on the returned value. Similarly, the parameter to equals is Object, rather than ObjectMethods. This is not required by Java's syntax rules, but rather a convention that enables other classes to work with this class. For example, the Collections API classes use the equals method to determine if an object is already in a set. If we wrote the method as equals(ObjectMethods om) instead of equals(Object o), the collections classes would call equals(Object o) as inherited from Object, which would test for identity using an == test. The hashCode method was written out of a sense of duty - Sun specifies that the behavior of hashCode "should be consistent with equals", meaning that if two items compare as equal, then they should have the same hash code - this will be revisited in the section on Collections.
Inheritance Conclusion
In this lesson of the Java tutorial you have learned:
The role of inheritance in a Java program How to declare and use classes that extend existing classes About methods inherited from Object
Exceptions
In this lesson of the Java tutorial, you will learn... 1. 2. 3. 4. 5. 6. 7. About the exception handling mechanism in Java Write try ... catch structures to catch expected exceptions Distinguish runtime exception classes from other exception classes Use finally blocks to guarantee execution of code Throw exceptions Define custom exception classes Understand initializer blocks
Exceptions
Exceptions are generated when a recognized condition, usually an error condition, occurs during the execution of a method
there are a number of standard error conditions defined in Java you may define your own error conditions as well
When an exception is generated, it is said to be thrown Java syntax includes a system for managing exceptions, by tracking the potential for each method to throw specific exceptions
for each method that could throw an exception, your code must inform the Java compiler that it could throw that specific exception the compiler marks that method as potentially throwing that exception, and then requires any code calling the method to handle the possible exception
you can try the "risky" code, catch the exception, and do something about it, after which the propagation of the exception ceases you can mark that this method throws that exception, in which case the Java runtime engine will throw the exception back to the method that called this one (since you must inform Java that this method throws the exception, any method that calls this one must be prepared to handle the exception)
So, if you use a method in your code that is marked as throwing a particular exception, the compiler will not allow that code unless you handle the exception Once an exception is thrown, it propagates backward up the chain of methods, from callees to callers, until it is caught
if the exception occurs in a try block, the JVM looks to the catch block(s) that follow to see if any of them match the exception type the first one that matches will be executed if none match, then this methods ends, and execution jumps to the method that called this one, at the point the call was made
If an exception is not caught in your code (which would happen if main was marked as throwing the exception) then the JVM will catch the exception, end that thread of execution, and print a stack trace There are some exceptions that the compiler does not enforce these rules on, those are called unchecked exceptions
Handling Exceptions
Let's say we are writing a method called getThatInt(ResultSet rs), and want to use the method getInt(int column) from the ResultSet passed in as a parameter:
public int getThatInt(ResultSet rs) { int i = 0; return rs.getInt(3); }
A look at the API listing for ResultSet tells us that the getInt() method throws SQLException, so we must handle that in our code
1. use try and catch
2. public int getThatInt(ResultSet rs) { 3. int i = 0; 4. try { 5. i = rs.getInt(3); 6. } 7. catch (SQLException e) { 8. System.out.println("Exception occurred!"); 9. System.out.println(e.getMessage()); 10. e.printStackTrace(); 11. } 12. return i; }
13. declare that the method will throw the exception and let our caller handle it
14. public int getThatInt(ResultSet rs) throws SQLException { 15. int i = 0; 16. i = rs.getInt(3); 17. return i; }
Note that although you are required to "handle" the exception, you aren't necessarily required to do anything useful about it!
Your decision as to which approach to use should be based on where you think responsibility for handling the exception lies - in the example above, the second approach is probably better; so that the code that works more closely with the SQL handles the exception
Exception Objects
When an exception is thrown, an exception object is created and passed to the catch block much like an parameter to a method
occurrence of an exception generates an object (an instance of a class in the exception hierarchy) containing information about the exception the exception object is passed to the code designated to catch the exception, which may then use methods of the exception object to help handle the situation
all exception classes inherit from Exception, which inherits from Throwable another class, Error, also inherits from Throwable your code must handle most exceptions, but generally should not attempt to handle Error subtypes (like OutOfMemoryError or StackOverflowError) RuntimeException is a subclass of Exception that is a base class for all the exception classes that you are not obligated to handle, but still might want to anyway (examples are ArithmeticException, from dividing by zero, NullPointerException, and ArrayIndexOutOfBoundsException)
So, there are several classes of exceptions you are not required to handle (shaded below)
these extend either Error or RuntimeException the ones you are required to handle are called checked exceptions generally, runtime exceptions can be prevent by good coding practices: o avoid null pointer exceptions by checking the reference first o check array indexes before using them to avoid ArrayIndexOutOfBoundsException o looking at the documentation for allowable parameter values, and testing them before passing them to a method will prevent IllegalArgumentException
there may be other code inside the try block, before and/or after the risky line(s) - any code that depends upon the risky code's success should be in the try block, since it will automatically be skipped if the exception occurs
Syntax
try { code risky code code that depends on the risky code succeeding }
There is usually at least one catch block immediately after the try block
Syntax
catch (ExceptionClassName exceptionObjectName) { code using methods from exceptionObjectName }
there can be more than one catch block, each one marked for a specific exception class the exception class that is caught can be any class in the exception hierarchy, either a general (base) class, or a very specific (derived) class
the catch block(s) must handle all checked exceptions that the try block is known to throw unless you want to throw that exception back to the method that called this one it is possible to have a try block without any catch blocks if you have a finally block o but any checked exceptions still need to be caught, or the method needs to declare that it throws them o we will cover finally later in this section
If an exception occurs within a try block, execution jumps to the first catch block whose exception class matches the exception that occurred (using an instanceof test)
???this would only be legal if the exception could be thrown by the method, either because it is marked to throw that exception, or because it is a RuntimeException
Note: you cannot catch an exception that would not occur in the try block
but you can mark a method as throwing an exception that it doesn't (this leaves open that possibility that an extending class can override the method and actually throw the exception)
Notes on try catch Blocks and Variable Initialization/Scope If declare a variable within a try block, it will not exist outside the try block, since the curly braces define the scope of the variable
you will often need that variable later, if nowhere else other than the catch or finally blocks, so you would need to declare the variable before the try
If you declare but don't initialize a variable before a try block, and the only place you set a value for that variable is in the try block, then it is possible when execution leaves the try ... catch structure that the variable never received a value
so, you would get a "possibly uninitialized value" error message from the compiler, since it actually keeps track of that sort of thing usually this happens with object references; you would also generally initialize them to null
i = x/y; System.out.println("x/y = " + i); j = x/z; System.out.println("x/z = " + j); } catch(ArithmeticException e) { System.out.println("Arithmetic Exception!"); } System.out.println("Done with test"); } }
Code Explanation
The program will print the first result, then fail while performing the division for the second equation. Execution will jump to the catch block to print our message on the screen Note: ArithmeticException is one of the few you are not required to catch, but you can still catch it if you wish.
} } }
Code Explanation
The line marked to comment out throws IOException, but is not in a try block, so the compiler rejects it. The second read attempt is within a try block, as it should be.
try to compile this code as is, then comment out the indicated line there is no way we can force an IOException from the keyboard to test the catch block
you can list a sequence of catch blocks, one for each possible exception remember that there is an object hierarchy for exceptions - since the first one that matches is used and the others skipped, you can put a derived class first and its base class later (you will actually get a compiler error if you list a more basic class before a derived class, as it is "unreachable code" )
Code Explanation
The code in the try block could throw NumberFormatException during the parsing, and ArithmeticException while doing the division, so we have catch blocks for those specific
cases. The more generic catch block for Exception would catch other problems, like NullPointerException.
if an exception causes a catch block to execute, the finally block will be executed after the catch block if an uncaught exception occurs, the finally block executes, and then execution exits this method and the exception is thrown to the method that called this method
Syntax
try { risky code block } catch (ExceptionClassName exceptionObjectName) { code to resolve problem } finally { code that will always execute }
In summary:
a try block is followed by zero or more catch blocks o if the catch block exception classes caught are related, the blocks must be listed in inheritance order from most derived to most basic there may one finally block as the last block in the structure there must be at least one block from the combined set of catch and finally after the try
It's possible to have a try block followed by a finally block, with no catch block
this is used to prevent an unchecked exception from exiting the method before cleanup code can be executed
int age; try { name = KeyboardReader.getPromptedString("What is your name: "); age = KeyboardReader.getPromptedInt("What is your age: "); System.out.println("Hello " + name); System.out.println("You are " + age); } catch (NumberFormatException e) { System.out.println("Number Format Exception occurred"); } catch (Exception e) { System.out.println("General Exception occurred"); } finally { System.out.println("Goodbye"); } } }
Code Explanation
when no exception occurs, the finally block will execute after the try if you force an exception by entering a non-numeric age, the catch block will execute, followed by the finally block ???if you enter 0 for age, the unhandled ArithmeticException will cause execution to back up the call stack, but only after executing the finally block
it will not execute if the try or catch blocks call System.exit() it will, however, run if the try or catch blocks execute a return statement
A return value from a finally block will supercede one from a try or catch block
so, stating that a method throws Exception is about as generic as you can get (stating that it throws Throwable is as generic as you can get, but not recommended) a method can throw more than one type of exception; in which case you would use a comma-separated list of exception types
In this way, the method is now marked as throwing that type of exception, and an code that calls this method will be obligated to handle it When you extend a class and override a method, you cannot add exceptions to the throws list
but, a base class method can list exceptions that it does not throw, in the expectation that an overriding method will throw the exception this is another example of the "inheritance cannot restrict access" principle we saw earlier
If main() throws an exception, the JVM, which runs under Java rules, will handle the exception (by printing a stack trace and closing down the offending thread - in a singlethreaded program, this will shut down the JVM).
Throwing an Exception
The keyword throw is used to trigger the exception-handling process (or, "raise" the exception, as it is often termed in other languages) That word is followed by an instance of a throwable object - i.e., an instance of a class that extends Throwable
usually, a new instance of an appropriate exception class is created to contain information about the exception
Example:
suppose a setAge() method expects a non-negative integer - we can have it throw an IllegalArgumentException if it receives a negative value it makes sense for the method that calls setAge() to do something about the problem, since it is where the illegal number came from so, we can declare setAge() as throws IllegalArgumentException
public void setAge(int age) throws IllegalArgumentException { if (age < 0) throw new IllegalArgumentException("Age must be >= 0"); else this.age = age;
A though exercise - our program to this point has been prone to potential bad numeric inputs when reading from the keyboard The parsing methods all throw NumberFormatException We could now put each line that requests a number inside a small loop The loop could be controlled by a boolean variable, perhaps with a name like isInvalid, and initially set to true (using the reverse approach is also a possible strategy)
inside the loop, we try the read and parse operations then, still in the try block, change the state of the boolean to one that will end the loop (because we wouldn't get to that step unless we succeeded) in the catch block, print an error message and request to try again
1. Where would you put this code? In the payroll main method or in the KeyboardReader class? Where is the solution?
similar to placing more strict access on the method, this would add restrict the derived class object in ways that a base class reference would be unaware of
If the derived class method does not throw the exception that the base class threw, it can either:
retain the exception in the throws list, even though it does not throw it - this would enable subclasses to throw the exception remove the exception from its throws list, thus blocking subsequent extensions from throwing that exception
If you have a base class method that does not throw an exception, but you expect that subclasses might, you can declare the base class to throw that exception
Constructs a new throwable with the specified cause and a detail Throwable(Throwable cause) message of (cause==null ? null : cause.toString()) (which typically contains the class and detail message of cause).
The forms involving a cause are used in situations like Servlets and Java Server Pages, where a specific exception is thrown by the JSP engine, but it may be rooted in an exception from your code
in both cases, a method in a base class is overridden by your code - since the writers of the base class did not know what specific exceptions your code might throw, and didn't want to specify something too broad like throws Exception, they settled on throws IOException, ServletException (or JSPException for Java Server Pages) you would try and catch for your expected exceptions, and repackage them inside ServletException objects if you did not want to handle them
getMessage()
printStackTrace()
printStackTrace(PrintStream same as above, but prints to the specified output stream (which stream) could be hooked to a log file, for example)
Also worth noting is that the Java Logging API has logging methods that will accept a Throwable parameter and make a log entry with the stack trace.
you could then add any fields or methods that you wish, although often that is not necessary you must, however, override any constructors you wish to use: Exception(), Exception(String message), Exception(String message, Throwable cause), Exception(Throwable cause) o usually you can just call the corresponding super-constructor
if you extend RuntimeException or one of its subclasses, your exception will be treated as a runtime exception (it will not be checked)
When a situation arises for which you would want to throw the exception, use the throw keyword with a new object from your exception class, for example:
Syntax
throw new ExceptionClassName(messageString);
Code Explanation
The thrower method randomly throws a NewException, by creating and throwing a new instance of NewException main tries to call thrower, and catches the NewException when it occurs
Exercise: Payroll-Exceptions02
Duration: 20 to 30 minutes.
Our payroll program can now handle things like a bad numeric input for pay rate (valid format, but not sensible, like a negative number) in a more comprehensive manner
we already are checking the numeric inputs from the keyboard, but there is no guarantee that later code will remember to do this - using an exception mechanism guarantees protection from invalid values
1. In the util package, create an exception class for InvalidValueException 2. Note that the Java API already contains a class for this purpose, IllegalArgumentException, but it is a RuntimeException - we would like ours to be a checked exception 3. In Employee (and potentially its subclasses), change the constructors that accept pay rate and the setPayRate methods to now throw that exception (a question to ask yourself - is it necessary to actually test the pay rate value anywhere other than in the Employee class setPayRate method?) 4. For any code that calls those constructors/methods, choose an appropriate approach to dealing with the potential exception Where is the solution?
Rethrowing Exceptions
An exception may be rethrown When we throw an exception, it does not necessarily have to be a new object
This allows us to partially process the exception and then pass it up to the method that called this one to complete processing
this is often used in servlets and JSPs to handle part of the problem (possibly just log it), but then pass the problem up to the servlet or JSP container to abort and send an error page
String s = "1234X"; try { Integer.parseInt(s); } catch (NumberFormatException e) { System.out.println("Bad number, passing buck to JVM"); throw e; }
the fillInStackTrace method for the exception object will replace the original information with information detailing the line on which fillInStackTrace was called as the origin of the exception
Initializer Blocks
Class properties that are object types can be initialized with a newly constructed object
public class MyClass { private Random rand = new java.util.Random(); private MegaString ms = new MegaString("Hello " + rand.nextInt(100)); private int x = rand.nextInt(100); . . . }
the MegaString class constructor code will run whenever a MyClass object is instantiated
the MyClass code won't compile - you cannot put a property declaration into a try ... catch structure and there is no place to state that the property declaration throws an exception
This is not absolutely necessary, since the initialization could be done in a constructor, where a try ... catch would be legal
but then it would need to be done in every constructor, which someone adding another constructor later might forget
Initializers are run in the order in which they appear in the code, whether standalone initializers, or initializers in a field declaration so, in the above code:
1. the Random object gets created for the first field 2. the MegaString gets the first generated random number 3. x gets the second generated random number
in our example, if we make the MegaString property static, its constructor will run when the class loads
again, this won't compile, but now there is no way even to defer the issue to the constructors, since the element is static
Again, the initializers are run in the order in which they appear in the code, when the class is loaded.
Assertions
Java 1.4 added the concept of assertions, code lines that test that a presumed state actually exists
if the state is not as presumed, then an AssertionError will be thrown assertions are not intended for testing values that could be expected; they are intended to be used when it is believed that a state exists, but we are not absolutely sure we have covered all the possible avenues that affect the state
Syntax
assert (condition)[: messageExpression];
The optional messageExpression will be converted to a String and passed as the message to the AssertionError constructor, so it cannot be a call to a function declared as void For example, perhaps we are using a third-party function that is specified to return a double value between 0 and 1, but we'd like to guarantee that is the case
Code Explanation
If the function returns a value outside of our expected range, like 5.0, the assertion condition will evaluate to false, so an AssertionError will be thrown with the message "thirdPartyFunction value 5.0 out of range" Note: in a 1.4 compiler, you must inform the compiler that you are compiling your code under Java 1.4 rules to use assertions, using the -source 1.4 command line switch:
Syntax
javac -source 1.4 ClassName.java
In Java 5 and later this is not necessary. Assertions are used for debugging a program, and usually not enabled for production runs
you must specifically enable assertions when you run the program, by using the command line switch -enableassertions (or -ea)
Syntax
java -enableassertions ClassName java -ea ClassName
Sun's "rules" for assertions emphasize that they will be disabled most of the time:
they should not be used for checking the values passed into public methods, since that check will disappear if assertions are not enabled the assertion code shouldn't have any side effects required for normal operation
Exceptions Conclusion
In this lesson of the Java tutorial you have learned:
how Java's exception handling mechanism works how to try and catch exceptions about the various types of checked and unchecked exceptions how to write exception classes how to throw exceptions how to use assertions
Inner Classes
In this lesson of the Java tutorial, you will learn... 1. To gain an understanding of the creation and use of inner classes
the outer class can freely instantiate inner class objects within its code; they are automatically associated with the outer class instance that created them code in some other class can instantiate an inner class object associated with a specific instance of the outer class if the inner class definition is public (and its containing class is public as well) if the inner class is static, then it can be instantiated without an outer class instance, otherwise, the inner class object must be attached to an instance of the outer class
create a type of object that is only needed within one class, usually for some short-term purpose
create a utility type of object that cannot be used elsewhere (which would allow the programmer to change it without fear of repercussions in other classes) create one-of-a-kind interface implementations (such as individualized event handlers) allow a sort of multiple inheritance, since the inner class may extend a different class than the outer class extends, and an inner class instance would have access to its private elements as well as the private elements of the outer class object it is attached to implement one-to-many relationships where the classes are tightly coupled (meaning that code for one or both of the classes needs access to many of the private elements of the other class) - the outer class would be the "one" side of the relationship, with the inner class being the "many" side provide a specialized form of callback, with which a class may pass very limited access to some of its internal components o the collections classes provide an iterator, a class that implements the Iterator interface to loop through the elements in the collection using hasNext and next methods o given that the internal structure of the collection may be complex, implementing the iterator as an inner class enables it to navigate the structure, while not exposing any other aspects of the collection to the outside world
Inner class code has free access to all elements of the outer class object that contains it, by name (no matter what the access level of the elements is) Outer class code has free access to all elements in any of its inner classes, no matter what their access term An inner class compiles to its own class file, separate from that of the outer class (the name of the file will be OuterClassName$InnerClassName.java, although within your code the name of the class will be OuterClassName.InnerClassName) - you cannot use the dollar sign version of the name in your code An inner class occupies its own memory block, separate from the outer class memory block
The definition of the inner class is always available for the outer class to use
no inner class objects are automatically instantiated with an outer class object outer class code may instantiate any number of inner class objects - none, one, or many
Code Explanation
MyOuter has one property, x; the inner class MyInner has one property, y the MyOuter constructor accepts two parameters; the first is used to populate x it creates one MyInner object, whose y property is populated with the second parameter note that the inner class has free access to the private outer class x element and the outer class has free access to the private inner class privateDisplay() method
The connection between the two classes is handled automatically The following diagram maps out the memory used by the example
Such an instance is automatically associated with the enclosing class instance that instantiated it.
Code Explanation
This code simply creates an instance of the outer class, MyOuter The MyOuter constructor creates an instance of MyInner as mentioned earlier
if the inner class is static, then it can exist without an outer class object, otherwise any inner class object you instantiate must belong to an outer class instance
For code that is not in the outer class, a reference to a static or non-static inner class object must use the outer class name, a dot, then the inner class name:
Syntax
OuterClassName.InnerClassName innerClassVariable
To create a non-static inner class object from outside the enclosing class, you must attach it to an outer class instance
Syntax
outerClassVariable.new InnerClassName(arguments)
For this purpose the new operator is a binary operator - it creates a new object of the type on its right belonging to the object on its left. To create a static inner class object from outside the enclosing class, you must still reference the outer class name
Syntax
OuterClassName.new InnerClassName(arguments)
Code Explanation
In the main method, the variable momi for the inner class instance is typed as MyInner.MyOuter It is populated by instantiating it attached to mo, using mo.new MyInner(102) It is generally recommended to avoid this syntax, and rely instead on outer class code to instantiate the inner class objects
making the inner constructors private or protected will enforce this practice (generally protected is better, since that would allow extensions of the outer class to also create inner class objects)
Note that we can access any public elements of the inner class instance, as in momi.publicDisplay(); You can create a new, unnamed, outer class object to hold the inner class object at the same time as creating the inner class object
Syntax
new OuterClassName(arguments).new InnerClassName(arguments)
For example:
momi = (new MyOuter(1)).new MyInner(101);
it is easer if the inner class objects can always be instantiated from the enclosing class object you can create a factory method to accomplish this
Code Explanation
For convenience this file contains both the main class and the FactoryOuter class (with package access).
the addInner method instantiates a FactoryInner object and adds it to the array (note that is still automatically associated with the FactoryOuter instance by the JVM, but we need our own mechanism for keeping track of the inner class instances we create) o a better approach would be to use one of the collections classes instead of an array, to avoid running out of room in the array
Referencing the Outer Class Instance From the Inner Class Code
If inner class code needs a reference to the outer class instance that it is attached to, use the name of the outer class, a dot, and this
remember that if there is no name conflict, there is no need for any special syntax for code in MyInner to obtain a reference to its MyOuter:
MyOuter.this
static members of the outer class are visible to the inner class, no matter what their access level non-static members of the outer class are not available, since there is not instance of the outer class to retrieve them from
An inner class may not have static members unless the inner class is itself marked as static
} public void printPaymentHistory() { for (Payment p : payments) { System.out.println(p); } } public class Payment { private double amount; private boolean posted; public Payment(double amount) { this.amount = amount; } public boolean process() throws TransactionException { if (!posted) { ytdPay += amount; posted = true; System.out.println(getFullName() + " paid " + amount); return true; } else { throw new TransactionException("Transaction already processed"); } } public String toString() { return getFullName() + " payment of " + amount; } } }
Code Explanation
Payment is an inner class to a simplified Employee, and, as an inner class, has free access to all private elements of Employee. Unlike a standalone payment class, this class can retrieve the employee name from the outer class instance. We also use this access to defer updating the year-to-date amounts until the payment is posted, via the process method. To get this degree of interaction between two separate classes would be difficult, since it would mean that either:
1. the ability to update ytdPay would have to be publicly available 2. Employee and Payment would have to be in the same package, with updating ytdPay achieved by using package access
Note that we have also separated the concepts of creating a payment from actually posting it
this gives us better control over transactions - note that a payment cannot be processed twice
Code Explanation
We have only one employee for simplicity. As we loop for each month, a payment is created for each. We try to process the June payment twice (remember that the array is zero-based, so January is month 0; this matches the behavior of the java.util.Date class) . The second attempt to process the payment should throw an exception which our catch block handles. We retrieve and print the year-to-date pay each time we process a payment. At the end we have the Employee object print the entire payment history created by our calls to the inner class' process method.
package employees; import finance.*; public class Employee { ---- Code Omitted ---public class Payment implements Payable { private double amount; private boolean posted; public Payment(double amount) { this.amount = amount; } public boolean process() throws TransactionException { if (!posted) { ytdPay += amount; posted = true; System.out.println(getFullName() + " paid " + amount); return true; } else { throw new TransactionException("Transaction already processed"); } } public String toString() { return getFullName() + " payment of " + amount; } } }
Code Explanation
This code goes one step further to create a Payment inner class that implements the Payable interface
// HR error causes attempt to process June paycheck twice if (month == 5) p.process(); } catch (TransactionException te) { System.out.println(te.getMessage()); } System.out.println("Ytd pay: " + e.getYtdPay()); } System.out.println("Employee Payment History:"); e.printPaymentHistory(); } }
Code Explanation
The only difference here is that we declare the variable holding the payments as Payable, hiding the fact that it is an inner class.