I have a very simple Java applet that just works.
import java.sql.*;
import org.apache.commons.lang3.*;
public class doQuery {
public static void main (String[] args) {
...
try {
...
} catch (Exception e) {
...
}
try {
...
try {
...
} catch (SQLException e) {
...
} finally {
...
}
} catch (SQLException e) {
...
}
}
}
It allows me to open a database, do some queries, and perform a series of outputs that is captured through stdio of a bash script, connections closed and then bash script emails the output.
However, I am looking to expand it, and I am stuck. I am programmer, just not a Java programmer. What I have come up with is something I hacked together. I want to add some functions, and more. I have tried to the function definitions in different places in the code, but it always generates compilation errors.
Can anyone provide some insight as to what I can change to enable me to add some functions? Generally programming say define the function before you attempt to use it, but I probably am not using the right keywords or something.
I can not figure out where to place a simple function like:
function display_number(number) {
return number + "";
}
in the source code that I can call and have it compile! :(
import java.sql.*;
import org.apache.commons.lang3.*;
public class doQuery {
public static void main (String[] args) {
...
try {
...
} catch (Exception e) {
...
}
try {
...
try {
...
} catch (SQLException e) {
...
} finally {
...
}
} catch (SQLException e) {
...
}
displayNumber(4); // Replace 4 with a variable to output or what not
}
private int displayNumber(int number) {
return number;
}
}
In Java you'll add your methods inside the scope of the class like so, when you want to use them call them inside of another function like in the example above. I'd recommend reading this link, it should give you a good understanding of how methods work, how to call them, etc.
If you just want a quick and easy function, here is a layout you can use.
public void display_number(int number) {
System.out.print(number);
}
Or if you prefer returning the number to use it somewhere else...
public int display_number() {
return number;
}
Your methods can be basically anywhere between the start { and the end } of your class, assuming you do not place it inside another method (such as the main method from your code). As far as anything else I recommend reading up on the subject, I am sure a google search will give you millions of examples of method calls.
Related
So, I had to create two files. One is a class definition. The other one uses the class' methods/fields.
(Artifact.java) Artifact Class definition:
public class Artifact {
int artNumber;
String arcName;
String artType;
int artYear;
double artWeight;
Artifact(int artNumber, String arcName, String artType, int artYear,double artWeight) {
this.artNumber = artNumber;
this.arcName = arcName;
this.artType = artType;
this.artYear = artYear;
this.artWeight = artWeight;
}
public void changeArtYear(int x) {
this.artYear = x;
}
public void changeArcName(String x) {
this.arcName = x;
}
public int getArtNumber() {
return artNumber;
}
public String getArcName() {
return arcName;
}
public String getArtType() {
return artType;
}
public int getArtYear() {
return artYear;
}
public double getArtWeight() {
return artWeight;
}
public String toString(){
return("The artifact #"+artNumber+" was discovered by "+arcName+". The artifact is made of "+artType+" and was discovered in "+artYear+". The artifact weighs "+artWeight+" kilograms.");
}
}
(ArtifactTester.java) Testing methods:
public class ArtifactTester {
public static void main(String[] args){
Artifact test = new Artifact(88888888,"ben","clay",1624,46.4);
System.out.println(test.toString()); //toString()
System.out.println(test.getArtWeight()); //getArtWeight()
System.out.println(test.getArtYear()); //getArtYear()
System.out.println(test.getArtType()); //getArtType()
System.out.println(test.getArcName()); //getArcName()
System.out.println(test.getArtNumber()); //getArtNumber()
test.changeArcName("zack");
test.changeArtYear(1400);
System.out.println(test.getArcName()); //getArcName()
System.out.println(test.getArtYear()); //getArtYear()
}
}
Anyways, my teacher to told me to add exception handling, but I am not sure where I would add exception handling.
Question: Is it possible to use exception handling in this situation?
Well to be blunt. Yes. Of course. You can use exception handling wherever and whenever you please (most of the time). Although, in this specific case I don't really see a good reason for it. But, I'll take your word for the need.
Now, as for where to handle exceptions, this is up to you. You can add exception handling in one of two places. You can either add exception handling when you call the methods like this:
try { //try executing a block of code which may throw exception
test.toString()
}
catch(Exception e) { //use Exception for all types of exceptions, or make it specific
//do something here if the exception is thrown
}
or you can excpetion handle in the methods themselves like so:
public void changeArtYear(int x) {
try{
this.artYear = x;
}
catch(Exception e){ //catch the exception that could be thrown
//do something
}
}
This should do the trick in your case if you want to add exception handling here. However, I would strongly urge you to learn exception handling and the different exceptions in Java, it is one of the most improtant fundamentals to programming in this language.
Also, let me point this out again: In this program, there is really no need to use exception handling except for practice. There is nothing here that would throw an exception for any reason. (Except maybe a NullPointerException if you passed a null parameter through one of your method calls)
Good Reference/Tutorial:
http://www.tutorialspoint.com/java/java_exceptions.htm
This site is an excellent java reference point in general, but specifically for your question today, this page shows you how to work with exceptions.
Is it possible to use exception handling in this situation?
I don't think so. You should probably go and ask your teacher.
In your code, Artifact is just a POJO (Plain Old Java Object). It would not throw any exceptions. All you do in the class is getters and setters, right? How can that throw any exceptions?
You can throw exceptions though. In your setters, you can check whether the argument is null before setting it to the fields. For example:
public void changeArcName(String x) {
if (x == null) throw new ArgumentException ("x is null!");
this.arcName = x;
}
Alternatively, you can just use brute force and use try...catch. like this:
Artifact test = new Artifact(88888888,"ben","clay",1624,46.4);
try {
System.out.println(test.toString()); //toString()
System.out.println(test.getArtWeight()); //getArtWeight()
System.out.println(test.getArtYear()); //getArtYear()
System.out.println(test.getArtType()); //getArtType()
System.out.println(test.getArcName()); //getArcName()
System.out.println(test.getArtNumber()); //getArtNumber()
test.changeArcName("zack");
test.changeArtYear(1400);
System.out.println(test.getArcName()); //getArcName()
System.out.println(test.getArtYear()); //getArtYear()
} catch (Exception ex) {
ex.printStackTrace ();
}
Warning: The catch block can never be reached!
I don't know whether the above is what your teacher wants. Just try both methods and hand it in and see what he/she says!
Something I've always been curious of
public class FileDataValidator {
private String[] lineData;
public FileDataValidator(String[] lineData){
this.lineData = lineData;
removeLeadingAndTrailingQuotes();
try
{
validateName();
validateAge();
validateTown();
}
catch(InvalidFormatException e)
{
e.printStackTrace();
}
}
//validation methods below all throwing InvalidFormatException
Is is not advisable to include the try/catch block within my Constructor?
I know I could have the Constructor throw the Exception back to the caller. What do you guys prefer in calling methods like I have done in Constructor? In the calling class would you prefer creating an instance of FileDataValidator and calling the methods there on that instance? Just interested to hear some feedback!
In the code you show, the validation problems don't communicate back to the code that is creating this object instance. That's probably not a GOOD THING.
Variation 1:
If you catch the exception inside the method/constructor, be sure to pass something back to the caller. You could put a field isValid that gets set to true if all works. That would look like this:
private boolean isValid = false;
public FileDataValidator(String[] lineData){
this.lineData = lineData;
removeLeadingAndTrailingQuotes();
try
{
validateName();
validateAge();
validateTown();
isValid = true;
}
catch(InvalidFormatException e)
{
isValid = false;
}
}
public boolean isValid() {
return isValid;
}
Variation 2:
Or you could let the exception or some other exception propagate to the caller. I have shown it as a non-checked exception but do whatever works according to your exception handling religion:
public FileDataValidator(String[] lineData){
this.lineData = lineData;
removeLeadingAndTrailingQuotes();
try
{
validateName();
validateAge();
validateTown();
}
catch(InvalidFormatException e)
{
throw new com.myco.myapp.errors.InvalidDataException(e.getMessage());
}
}
Variation 3:
The third method I want to mention has code like this. In the calling code you have to call the constructor and then call the build() function which will either work or not.
String[] lineData = readLineData();
FileDataValidator onePerson = new FileDataValidator();
try {
onePerson.build(lineData);
} catch (InvalidDataException e) {
// What to do it its bad?
}
Here is the class code:
public FileDataValidator() {
// maybe you need some code in here, maybe not
}
public void build(String[] lineData){
this.lineData = lineData;
removeLeadingAndTrailingQuotes();
try
{
validateName();
validateAge();
validateTown();
}
catch(InvalidFormatException e)
{
throw new com.myco.myapp.errors.InvalidDataException(e.getMessage());
}
}
Of course, the build() function could use a isValid() method that you call to see if its right but an exception seems the right way to me for the build function.
Variation 4:
The fourth method I want to mention is what I like best. It has code like this. In the calling code you have to call the constructor and then call the build() function which will either work or not.
This sort of follows the way JaxB and JaxRS work, which is a similar situation to what you have.
An external source of data - you have a file, they have an incoming message in XML or JSON format.
Code to build the objects - you have your code, they have their libraries of code working according the specifications in the various JSRs.
Validation is not tied to the building of the objects.
The calling code:
String[] lineData = readLineData();
Person onePerson = new Person();
FileDataUtilities util = new FileDataUtilities();
try {
util.build(onePerson, lineData);
util.validate(onePerson);
} catch (InvalidDataException e) {
// What to do it its bad?
}
Here is the class code where the data lives:
public class Person {
private Name name;
private Age age;
private Town town;
... lots more stuff here ...
}
And the utility code to build and validate:
public FileDataValidator() {
// maybe you need some code in here, maybe not
}
public void build(Person person, String[] lineData){
this.lineData = lineData;
removeLeadingAndTrailingQuotes();
setNameFromData(person);
setAgeFromData(person);
setTownFromData(person);
}
public boolean validate(Person person) {
try
{
validateName(person);
validateAge(person);
validateTown(person);
return true;
}
catch(InvalidFormatException e)
{
throw new com.myco.myapp.errors.InvalidDataException(e.getMessage());
}
}
You should consider the static factory pattern. Make your all-arguments constructor private. Provide a static FileDataValidator(args...) method. This accepts and validates all the arguments. If everything is fine, it can call the private constructor and return the newly created object. If anything fails, throw an Exception to inform the caller that it provided bad values.
I must also mention that this:
catch (Exception e) {
printSomeThing(e);
}
Is the deadliest antipattern you could do with Exceptions. Yes, you can read some error values on the command line, and then? The caller (who provided the bad values) doesn't get informed of the bad values, the program execution will continue.
My preference is for exceptions to be dealt with by the bit of code that knows how to deal with them. In this case I would assume that the bit of code creating a FileDataValidator knows what should happen if the file data is not valid, and the exceptions should be dealt with there (I am advocating propagating to the caller).
Whilst discussing best practice - the class name FileDataValidator smells to me. If the object you're creating stores file data then I would call it FileData - perhaps with a validate method? If you only want to validate your file data then a static method would suffice.
There are some task that should't be done in parallel, (for example opening a file, reading, writing, and closing, there is an order on that...)
But... Some task are more like a shoping list, I mean they could have a desirable order but it's not a must..example in communication or loading independient drivers etc..
For that kind of tasks,
I would like to know a java best practice or pattern for manage exceptions..
The java simple way is:
getUFO {
try {
loadSoundDriver();
loadUsbDriver();
loadAlienDetectorDriver();
loadKeyboardDriver();
} catch (loadSoundDriverFailed) {
doSomethingA;
} catch (loadUsbDriverFailed) {
doSomethingB;
} catch (loadAlienDetectorDriverFailed) {
doSomethingC;
} catch (loadKeyboardDriverFailed) {
doSomethingD;
}
}
But what about having an exception in one of the actions but wanting to
try with the next ones??
I've thought this approach, but don't seem to be a good use for exceptions
I don't know if it works, doesn't matter, it's really awful!!
getUFO {
Exception ex=null;
try {
try{ loadSoundDriver();
}catch (Exception e) { ex=e; }
try{ loadUsbDriver();
}catch (Exception e) { ex=e; }
try{ loadAlienDetectorDriver();
}catch (Exception e) { ex=e; }
try{ loadKeyboardDriver()
}catch (Exception e) { ex=e; }
if(ex!=null)
{ throw ex;
}
} catch (loadSoundDriverFailed) {
doSomethingA;
} catch (loadUsbDriverFailed) {
doSomethingB;
} catch (loadAlienDetectorDriverFailed) {
doSomethingC;
} catch (loadKeyboardDriverFailed) {
doSomethingD;
}
}
seems not complicated to find a better practice for doing that.. I still didn't
thanks for any advice
Consider the execute around idiom.
Another option (which isn't really all that different, it just decouples them more) is to do each task in a separate thread.
Edit:
Here is the kind of thing I have in mind:
public interface LoadableDriver {
public String getName();
public void loadDriver() throws DriverException;
public void onError(Throwable e);
}
public class DriverLoader {
private Map<String, Exception> errors = new HashMap<String, Exception>();
public void load(LoadableDriver driver) {
try {
driver.loadDriver();
} catch (DriverException e) {
errors.put(driver.getName(), e);
driver.onError(e);
}
}
public Map<String, Exception> getErrors() { return errors; }
}
public class Main {
public void loadDrivers() {
DriverLoader loader = new DriverLoader();
loader.loadDriver(new LoadableDriver(){
public String getName() { return "SoundDriver"; }
public void loadDriver() { loadSoundDriver(); }
public void onError(Throwable e) { doSomethingA(); }
});
//etc. Or in the alternative make a real class that implements the interface for each driver.
Map<String, Exception> errors = loader.getErrors();
//react to any specific drivers that were not loaded and try again.
}
}
Edit: This is what a clean Java version would ultimately look like if you implemented the drivers as classes (which is what the Java OO paradigm would expect here IMHO). The Main.loadDrivers() method would change like this:
public void loadDrivers(LoadableDriver... drivers) {
DriverLoader loader = ...
for(LoadableDriver driver : drivers) {
loader.load(driver);
}
//retry code if you want.
Set<LoadableDriver> failures = loader.getErrors();
if(failures.size() > 0 && tries++ > MAX_TRIES) {
//log retrying and then:
loadDrivers(drivers.toArray(new LoadableDriver[0]));
}
}
Of course I no longer use a map because the objects would be self-sufficient (you could get rid of the getName() method as well, but probably should override toString()), so the errors are just returned in a set to retry. You could make the retry code even simpler if each driver was responsible for knowing how often it should it retry.
Java won't look as nice as a well done C++ template, but that is the Java language design choice - prefer simplicity over complex language features that can make code hard to maintain over time if not done properly.
Try this:
protected void loadDrivers() {
loadSoundDriver();
loadUsbDriver();
loadAlienDetectorDriver();
loadKeyboardDriver();
}
Then:
protected void loadSoundDriver() {
try {
// original code ...
}
catch( Exception e ) {
soundDriverFailed( e );
}
}
protected void soundDriverFailed( Exception e ) {
log( e );
}
This gives subclasses a chance to change the behaviour. For example, a subclass could implement loading each driver in a separate thread. The main class need not care about how the drivers are loaded, nor should any users of the main class.
IMO, for your case, if the exception is "ignorable" it's best if the "loadSoundDriver" method catches the exception and simply returns an error.
Then in the function that loads stuff, you can record all the errors and at the end of the sequence, decide what to do with them.
[edit]
Something like this:
// init
MyError soundErr = loadSoundDriver();
MyError otherErr = loadOtherDriver();
if(soundErr!=null || otherErr !=null){
// handle the error(s)
}
Just surround every single load operation with its own try / catch block.
try {
loadSoundDriver();
} catch (loadSoundDriverFailed) {
doSomethingA;
}
try {
loadUsbDriver();
} catch (loadUsbDriverFailed) {
doSomethingB;
}
// ...
So you can handle every exception by itself and continue processing the oder operations.
I am writing a parser for csv-files, and sometimes I get NumberFormatException. Is there an easy way to print the argument value that caused the exception?
For the moment do I have many try-catch blocks that look like this:
String ean;
String price;
try {
builder.ean(Long.parseLong(ean));
} catch (NumberFormatException e) {
System.out.println("EAN: " + ean);
e.printStackTrace();
}
try {
builder.price(new BigDecimal(price));
} catch (NumberFormatException e) {
System.out.println("Price: " + price);
e.printStackTrace();
}
I would like to be able to write something like:
try {
builder.ean(Long.parseLong(ean));
} catch (NumberFormatException e) {
e.printMethod(); // Long.parseLong()
e.printArgument(); // should print the string ean "99013241.23"
e.printStackTrace();
}
Is there any way that I at least can improve my code? And do this kind of printing/logging more programmatically?
UPDATE: I tried to implement what Joachim Sauer answered, but I don't know if I got everything right or if I could improve it. Please give me some feedback. Here is my code:
public class TrackException extends NumberFormatException {
private final String arg;
private final String method;
public TrackException (String arg, String method) {
this.arg = arg;
this.method = method;
}
public void printArg() {
System.err.println("Argument: " + arg);
}
public void printMethod() {
System.err.println("Method: " + method);
}
}
The Wrapper class:
import java.math.BigDecimal;
public class TrackEx {
public static Long parseLong(String arg) throws TrackException {
try {
return Long.parseLong(arg);
} catch (NumberFormatException e) {
throw new TrackException(arg, "Long.parseLong");
}
}
public static BigDecimal createBigDecimal(String arg) throws TrackException {
try {
return new BigDecimal(arg);
} catch (NumberFormatException e) {
throw new TrackException(arg, "BigDecimal.<init>");
}
}
}
Example of use:
try {
builder.ean(TrackEx.createBigDecimal(ean));
builder.price(TrackEx.createBigDecimal(price));
} catch (TrackException e) {
e.printArg();
e.printMethod();
}
EDIT: Same question but for .NET: In a .net Exception how to get a stacktrace with argument values
You can easily implement such detailed information on custom-written exceptions, but most existing exceptions don't provide much more than a detail message and a causing exception.
For example you could wrap all your number parsing needs into a utility class that catches the NumberFormatException and throws a custom exception instead (possibly extending NumberFormatException).
An example where the some additional information is carried via the exception is SQLException which has
a getErrorCode() and a getSQLState() method.
Create a method such as private parse (String value, int type) which does the actual parsing work including exception handling and logging.
parse(ean, TYPE_LONG);
parse(price, TYPE_BIG_DECIMAL);
Where TYPE_ is just something to tell the method how it should parse the value.
Similar to another suggestion, you could extract Long.parseLong(ean) into it's own method (either privately within the class or public on another utility sort of class).
This new method would handle any custom logic AND you could test it in isolation. Yay!
I have an ArrayList and wish to be able to call an index and use the returned string for a method call.
e.g.
stringList.get(2)();
Is there any way I could go about this?
So you want the returned String to be used as the name of the method to call?
You can do that using reflection, but I'd strongly discourage this.
Instead you will want to look into implementing a strategy pattern for example.
Yes, there is a way to use the returned string from the list for a method call.
As others users already pointed out, you need to use Reflection API. Can be complicated deal with that, depends on the particular scenario you are facing.
Just to show you the basic approach in a concrete but simplified example, I create this code. Copy it and play changing the index, and creating new methods with parameters after learn the basics of the API.
import java.lang.reflect.*;
import java.util.*;
public class DemoReflection {
public static void main(String[] args) {
List<String> myStringList = new ArrayList<String>();
myStringList.add(0, "foo");
myStringList.add(1, "printStr");
myStringList.add(2, "otherMethod");
myStringList.add(3, "stackoverflow");
int index = 3;
String methodName = myStringList.get(index);
try {
Class<?> c = Class.forName("DemoReflection");
Object obj = c.newInstance();
Method method = c.getDeclaredMethod(methodName, null);
method.invoke(obj, null);
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
public void stackoverflow() {
System.out.println("Stackoverflow rules!");
}
public void printStr() {
System.out.println("Method printStr invoked...");
}
}
First of call you can't call a method in java without an object to call it on. Is that in the list also.
It would be better to have a list of Runnable...
List<Runnable> runnables = ...
runnables.get(2).call();
If you have the object you need to call, and you want to use reflection (can be slow) then commons-beans can help make it simple. See http://commons.apache.org/beanutils
import org.apache.commons.beanutils.MethodUtils;
Object target = ...
List<String> methodNames = ...
MethodUtils.invokeMethod(target, methodNames.get(2), /*args*/ null);
To give better I'd advice I'd need to know more about the problem you are trying to solve.
One would have to use reflection. See http://tutorials.jenkov.com/java-reflection/methods.html.
Does the ArrayList have to contain Strings?
Otherwise you could populate it with java.lang.reflect.Method instances, and call Method.invoke() on the returned instance.
If I understand your needs, here is an example based on an interface; the list then contains implementations of the interface rather than method names:
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) throws Exception {
List<Action> actions = new ArrayList<Action>();
actions.add(new Action(){
public void execute() {
System.out.println("Action 0");
}});
actions.add(new Action(){
public void execute() {
System.out.println("Action 1");
}});
actions.get(0).execute();
actions.get(1).execute();
}
static interface Action{
void execute();
}
}
Or maybe polymorphism and a factory method would be a better idea. You'd have to circumscribe the methods you'll be able to call, but that wouldn't be a bad idea.
If you want the full Monty, and you're using Java 6, maybe you can create a JavaScript function object and invoke it with Rhino.
Or if you insist on making the idea work regardless of any obstacles, you could call out to a dynamic language like JRuby or Clojure, both of which are willing to eval() a String.
Or Jython or Groovy or...
In Java - no way. That's not a Java language feature. Your're hoping for something like
// NOT VALID JAVA
String myColoring = paintBlackOrWhite() ? "black" : "white";
myColoring(myBathroomWall);
// NOT VALID JAVA
Like others suggested, a pure technical solution would be using reflections: take the result string, find the corresponding method and invoke it. A technical solution could even be a map like
Map<String, java.lang.reflect.Method> myMethods;
and do something like
get("black").invoke(myObject, myParams);
but all of that is nice to know and you shouldn't use it unless forced or you have a concrete problem where even SO doesn't have a solution ;)