Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Lecture 8 CS 202 Errors Three types of errors • Syntax/Compile time • Runtime • Logic Errors Syntax/Compiletime Errors – Incorrect Java, caught by IDE or compiler int x == 0; Errors Runtime errors occur when an operation is impossible to carry out. Without additional handling, they cause the application to crash: • Read from a file that does not exist • Integer.parseInt(1.2); public static void main(String[] args){ int quotient = 0; for(int counter = 10; counter >=0; counter--){ System.out.print("10 / " + counter + " = "); quotient = 10/counter; System.out.println (quotient); } } Errors Logic Errors • Logical problems in the application • Cause incorrect results, not crashes String[] options = {"Yes", "No"}; int buy = 0; JOptionPane.showOptionDialog(null, "Place Order?", "Buy Dialog", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, "Yes"); if(x ==0); buyProduct(); Stack Trace • A stack trace is a list of method calls and code line numbers, usually seen when an error occurs: • You should love a stack trace like a mother who only criticizes you for your own good. • Note that you can tell what line of your code was executing when the error occurred, but you may have to read several lines of the trace to get to it. Exceptions Definitions of "exception:" • Wikipedia: "An anomalous event requiring special processing" • Liang Introduction To Java Programming, referring to Java exceptions specifically: "An object that represents an error or condition that prevents execution from proceeding normally." • In Java, an exception is an object! • Various kinds of Exceptions are defined in different Exception classes. • Exception classes have methods; the ones you are likely to use involve stack traces and error messages. • Exceptions are "raised" or "thrown" by code, either written by you or by the author of a class you are using. Exceptions: • You can create your own exceptions to deal with the problems that are likely to arise in your programs, but for now, use the ones that are built in to the Java API. You have already encountered many of these • This code will raise a StackOverflowException : public class Demo { int x; public Demo(int oldX){ x = oldX + 1; System.out.println(x); Demo d = new Demo(x); } public static void main(String[] args) { Demo demo = new Demo(1); } } Exceptions • Try/Catch: • Run an exception-prone operation in try{}; if an exception occurs, deal with it in catch{} • Optional finally{} runs after the try code, whether or not an exception occurs Try…catch…finally Try-Catch-Finally try{ error-prone code } catch(TypeOfException nameForException){ what to do if this type of exception occurs } catch(OtherTypeOfException nameForException){ what to do if this type of exception occurs } catch(Exception ex){ what to do if any other type of exception occurs } … finally{ code to execute afterwards, whether or not an exception occurred } Throwing Exceptions • The exceptions we have seen so far are thrown by code you did not write • You can also check for exceptional conditions and throw exceptions, either standard ones or your own • See the textbook for syntax for creating your own exception types. Only do this when none of the standard ones seem correct. Try-Catch-Finally • Consider this error-prone code: public static void main(String[] args) { Scanner input = new Scanner(System.in); System.out.println("Enter two numbers:"); double num1 = input.nextDouble(); double num2 = input.nextDouble(); double result = num1 / num2; System.out.println(num1 + "/" + num2 + "=" + result); input.close(); } Try-Catch-Finally public static double quotient(double num1, double num2) { if (num2 == 0) throw new ArithmeticException("Divisor cannot be zero"); return num1 / num2; } public static void main(String[] args) { Scanner input = new Scanner(System.in); System.out.println("Enter two numbers:"); try { double num1 = input.nextDouble(); double num2 = input.nextDouble(); double result = quotient(num1, num2); System.out.println(num1 + "/" + num2 + "=" + result); } catch (ArithmeticException ex) { System.out.println(ex.getMessage()); } finally { input.close(); } System.out.println("festivities continue without a crash!"); } Checked Exceptions • The compiler will force you to handle certain kinds of exceptions; these are called Checked Exceptions. • Recall the file operations in week 2. Since file I/O is so errorprone, many file operations throw exceptions which you must catch in order to use the File, PrintWriter, etc. classes. Simulators • Imagine you need data to test software that will be used to process real-world measurements, like the ages of college students • Sometimes you might want linearly-distributed data, but Gaussian (normal) distributions are often more realistic • Random.nextGaussian() returns a double from a normal distribution with standard deviation = 1 and mean = 0. Multiply it by the desired STD and then add the desired mean package simulator; import java.util.Arrays; public class Grader { private double average; private double std; private int classSize; private double[] grades; private final double MINGRADE = 0; private final double MAXGRADE = 100; public enum GradingType { LINEAR, GAUSSIAN }; public Grader(double avgIn, double stdIn, int classSizeIn) { average = avgIn; std = stdIn; classSize = classSizeIn; } public static void main(String[] args) { Grader grd = new Grader(80d, 10d, 20); grd.grade(GradingType.LINEAR); grd.grade(GradingType.GAUSSIAN); } private void grade(GradingType type) { Simulator sim = new Simulator(); if (type == GradingType.LINEAR) grades = sim.getLinearData(classSize, MINGRADE, MAXGRADE); if (type == GradingType.GAUSSIAN) grades = sim.getGaussianData(average, std, classSize, MINGRADE, MAXGRADE); System.out.println("\nData using distribution type: " + type + "\n"); for (int i = 0; i < grades.length; i++) { System.out.print("Student #" + i + " received a grade of "); System.out.printf("%3.1f\n", grades[i]); } Arrays.sort(grades); System.out.println("Here are the sorted values from the simulator:"); for (double d : grades) System.out.printf("%3.1f\n",d); } } package simulator; import java.util.Random; public class Simulator { private static double[] nums; public double[] getGaussianData(double mean, double std, int count, double min, double max) { Random r = new Random(); nums = new double[count]; double randDoub; for (int counter = 0; counter < nums.length; counter++){ randDoub = r.nextGaussian() * std + mean; // it's pretty hard to set limits for the values in a good way, so here is a hacky way. if(randDoub > max) randDoub = max; if(randDoub < min) randDoub = min; nums[counter] = randDoub; } return nums; } public double[] getLinearData(int count, double min, double max) { // it would be better to make sure max < min first, but I am not implementing this in this example Random r = new Random(); nums = new double[count]; double randDoub; for (int counter = 0; counter < nums.length; counter++){ randDoub = r.nextDouble() * (max - min) + min; nums[counter] = randDoub; } return nums; } } Separate Things That Are Likely To Change Independently • Grader is domain-specific (only useful for a narrow type of problem, in this case grading schoolwork) • Simulator, on the other hand, does not contain anything that shows it is from an application that simulates grading. It could be used to generate test data for a very wide variety of problems • This is an example of an important principle in software engineering. Separate the general from the specific, and separate things you can probably reuse from things you can't. If two things are likely to change independently of each other, don’t combine them. – "When all you have is a hammer, everything looks like a nail" – folk proverb – "If I had a hammer, I'd hammer in the morning, I'd hammer in the evening, all over this land. I'd hammer out danger; I'd hammer out a warning; I'd hammer out love between my brothers and my sisters, all over this land." –Pete Seeger Instanceof • The next demo uses Java's instanceof operator, which determines whether an object is an instance of a particular class • The syntax of instanceof may be counterintuitive; the keyword does not use camel case and there are no parentheses around the class name • The next slide shows a simple demo of instanceof Instanceof package demos; public class Demo { Object myObject; public void setMyObject(Object o) { myObject = o; } public Object getMyObject() { return myObject; } public static void main(String[] args) { Demo demo = new Demo(); String newObject = new String("John"); demo.setMyObject(newObject); Object o = demo.getMyObject(); if (o instanceof String) System.out.println("\"" + o + "\"" + " is a String!"); else System.out.println("not a String!"); Object arch = new Archimedes(); demo.setMyObject(arch); Object o2 = demo.getMyObject(); if (o2 instanceof String) System.out.println("\"" + 02 + "\"" + " is a String!"); else System.out.println(o2 + " is not a String!"); } }