Java - Converting String into instance of interface - java

Working with the Filter Design pattern.
I have a Context interface, there are concrete classes implementing this interface, called f.e. BehavioralPurpose and StructuralPurpose.
What I'm currently trying to achieve is that when I add CreationalPurpose class, and give it as an option in the front-end, everything will continue working smoothly (filtering)
I have a jsp that will return a value like 'structural', 'behavioral' etc.
But now I will need to create an instance of the StructuralPurpose class. Like Context context= new StructuralPurpose(); But I do not know if I will get 'structural' or 'behavioral' and I do not want to solve this by adding if statements, mainly because, if someone would add a new Purpose class, that person does not have to add another if statement to this filter.
So is this possible? I was thinking about maybe having a string called purposeString and solving the issue like so:
String purpose = purposeString + "Purpose";
Context context = Class.forName(purpose).newInstance();
But this will result into an error saying: Type mismatch: cannot convert from capture#1-of ? to Context
So is there any way this is possible?
With a cast of (Context) Class.forName(purpose).newInstance(); I will get a ClassNotFoundException. The classes are in different packages, not sure if this matters. Here is the code i used:
String behav = "filter.Behavioral";
String purpo = behav+"Purpose";
Context behavioral = null;
try {
behavioral = (Context) Class.forName(purpo).newInstance();
} catch (InstantiationException e) {
System.out.println("\n basically failed");
} catch (IllegalAccessException e) {
System.out.println("\n not allowed");
} catch (ClassNotFoundException e) {
System.out.println("\n not found");
}
Just for testing purposes only, this code will return 'not found'.

In general, this is not a good practice to allow user to dynamically create objects like this, unless you have a limited number of situations & you have exact control over all aspects and possible exceptions.
Anyway, if you have enough reasons to do this, you just need to cast it:
try
{
String purpose = "com.path.to.your.package." + purposeString + "Purpose";
Context context = (Context) Class.forName(purpose).newInstance();
}
catch(ClassNotFoundException ex)
{
ex.printStackTrace();
}

Related

Best practices - 2 Method with same functionality - one throws exception and another suppress

As it doesn't make sense to overload methods based on the exception clause.
Most of the times when we are writing the code, we came into a scenario where
we want some piece of code to throw an exception so that we can handle it accordingly
some times for the same piece of code we just want to ignore that exception
Example below -
// It is used at many places and we just want to take specific action if any exception is coming,
// like retry if SQLExceptions
private List<Contact> getContacts() throws Exceptions{
List<Contact> contacts = null;
try {
contacts = contactDao.getContacts();
} catch (SQLException ex) {
logger(ex);
throw ex;
}
return contacts;
}
private List<Contact> getContacts1() throws Exceptions{
List<Contact> contacts = null;
try {
contacts = contactDao.getContacts();
} catch (SQLException ex) {
logger(ex);
}
return contacts;
}
// It is used at some places and I want this method to throw an exception,
// I want to handle it using null check
What should be the correct ways to write such methods.
IMHO, you should have two methods since they'd do different things inside.
For example, at ROR, there is a convention to handle your problem. When methods are finished with a ! means that if something goes wrong an exception will be raised. So, when you want to save an item you can call
save!: it raises an exception if the item can't be saved or returns the item itself
or save: it doesn't raise anything and returns true or false according to the state of the operation
I'm not sure which language you are coding but maybe it could be helpful to find your language convention. If there is no convention at your current language/framework you could define one with your team and use it internally. For example, you can define a getContacts_unsafe method ann know that suffix means it doesn't raise an exception

How to ignore Exceptions in Java

I have the following code:
TestClass test=new TestClass();
test.setSomething1(0); //could, but probably won't throw Exception
test.setSomething2(0); //could, but probably won't throw Exception
I would like to execute: test.setSomething2(0); even if test.setSomething(0) (the line above it) throws an exception. Is there a way to do this OTHER than:
try{
test.setSomething1(0);
}catch(Exception e){
//ignore
}
try{
test.setSomething2(0);
}catch(Exception e){
//ignore
}
I have a lot of test.setSomething's in a row and all of them could throw Exceptions. If they do, I just want to skip that line and move to the next one.
For clarification, I don't care if it throws an Exception, and I can't edit the source code of the code which throws this exception.
THIS IS A CASE WHERE I DON'T CARE ABOUT THE EXCEPTIONS (please don't use universally quantified statements like "you should never ignore Exceptions"). I am setting the values of some Object. When I present the values to a user, I do null checks anyway, so it doesn't actually matter if any of the lines of code execute.
try {
// Your code...
} catch (Exception ignore) { }
Use the word ignore after the Exception keyword.
There is no way to fundamentally ignore a thrown exception. The best that you can do is minimize the boilerplate you need to wrap the exception-throwing code in.
If you are on Java 8, you can use this:
public static void ignoringExc(RunnableExc r) {
try { r.run(); } catch (Exception e) { }
}
#FunctionalInterface public interface RunnableExc { void run() throws Exception; }
Then, and implying static imports, your code becomes
ignoringExc(() -> test.setSomething1(0));
ignoringExc(() -> test.setSomething2(0));
IntelliJ Idea IDE suggests to rename a variable to ignored
when it isn't used.
This is my sample code.
try {
messageText = rs.getString("msg");
errorCode = rs.getInt("error_code");
} catch (SQLException ignored) { }
Unfortunately no, there isn't, and this is by intention. When used correctly, exceptions should not be ignored as they indicate that something didn't work and that you probably shouldn't continue down your normal execution path. Completely ignoring exceptions is an example of the 'Sweep it under the rug' anti-pattern, which is why the language doesn't support doing so easily.
Perhaps you should look at why TestClass.setSomething is throwing exceptions. Is whatever you're trying to 'test' really going to be valid if a bunch of setter methods didn't work correctly?
You can't ignore exception in Java. If a method declares being able to throw something this is because something important can't be done, and the error can't be corrected by the method designer. So if you really wan't to simplify your life encapsulate the method call in some other method like this :
class MyExceptionFreeClass {
public static void setSomething1(TestClass t,int v) {
try {
t.setSomething1(v);
} catch (Exception e) {}
public static void setSomething2(TestClass t,int v) {
try {
t.setSomething2(v);
} catch (Exception e) {}
}
and call it when you need it:
TestClass test=new TestClass();
MyExceptionFreeClass.setSomething1(test,0);
MyExceptionFreeClass.setSomething2(test,0);
You should not ignore Exceptions. You should handle them. If you want to make your test code simple, then add the try-catch block into your functions. The greatest way to ignore exceptions is to prevent them by proper coding.
I know this is old, but I do think there are occasions when you want to ignore an exception. Consider you have a string that contains a delimited set of parts to be parsed. But, this string can sometimes contain say, 6 or 7 or 8 parts. I don't feel that checking the len each time in order to establish an element exists in the array is as straight forward as simply catching the exception and going on. For example, I have a string delimited by '/' character that I want to break apart:
public String processLine(String inLine) {
partsArray = inLine.split("/");
//For brevity, imagine lines here that initialize
//String elems[0-7] = "";
//Now, parts array may contains 6, 7, or 8 elements
//But if less than 8, will throw the exception
try {
elem0 = partsArray[0];
elem1 = partsArray[1];
elem2 = partsArray[2];
elem3 = partsArray[3];
elem4 = partsArray[4];
elem5 = partsArray[5];
elem6 = partsArray[6];
elem7 = partsArray[7];
catch (ArrayIndexOutOfBoundsException ignored) { }
//Just to complete the example, we'll append all the values
//and any values that didn't have parts will still be
//the value we initialized it to, in this case a space.
sb.append(elem0).append(elem1).append(elem2)...append(elem7);
//and return our string of 6, 7, or 8 parts
//And YES, obviously, this is returning pretty much
//the same string, minus the delimiter.
//You would likely do things to those elem values
//and then return the string in a more formatted way.
//But was just to put out an example where
//you really might want to ignore the exception
return sb.toString();
}
Those who write empty catch blocks shall burn in the Hell for the eternity.
Or worse, they will be forced to debug the damn rubbish they wrote forever and ever.
That said, one thing you might want to do is writing exception handling in a less verbose way. The NoException library is very good at that.

String inside dot operators

I'm pretty sure this is impossible (considering it is such abysmal programming practice), but I'm going to ask anyway.
In Java, is there a way to use a string in place of a method name (or something else) using the dot operator?
For example: java.stringname.NumericShaper(); where stringname = "awt.font"
I'm trying to put some repetitive code into an iterative loop. For example, one of my variables is "Settings.can1.baud", and I want to iterate the "can1" part each time I go through the loop. Perhaps there's a better way to do this?
I'm new to Java programming, so I'm not sure that made any sense...
If you mean you have a bunch of members called can1, can2, can3, etc., then you should use an array or a collection instead.
It is possible to do what you want using reflection. But it's fiddly, bad practice (often), and unnecessary in this case.
You could do this using reflection:
try {
//loop over stringnames?
String stringname = "awt.font";
Class<?> numericShaperClass = Class.forName("java." + stringname + ".NumericShaper");
NumericShaper numericShaper = (NumericShaper) numericShaperClass.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
As for the second part of your question, you can access the member variables of your Properties class using the Class.getField() method.
Using reflection might be overkill in this situation and can result in some pretty unreadable, and possibly slow code.

Is it ok to handle a class metadata through reflection to ensure a DRY approach?

The title might seem unsettling, but let me explain.
I'm facing an interesting challenge, where I have a hierarchy of classes that have associated an object that stores metadata related to each one of its attributes (an int-valued enum with edit flags like UPDATED or NO_UPDATE).
The problem comes when merging two objects, because I dont want to check EVERY field on a class to see if it was updated and skip or apply the changes.
My idea: Reflection.
All the objects are behind an interface, so I could use IObject.class.getMethods() and iterate over that array in this fashion:
IClass class = //Instance of the first class;
IAnotherClass anotherClass = //Instance of the second class;
for(Method m : IObject.class.getMethods()) {
if(m.getName().startsWith("get")) {
try {
//Under this method (which is a getter) I cast it on
//both classes who implement interfaces that extend an
//interface that defines the getters to make them
//consistent and ensure I'll invoke the same methods.
String propertyClass = (String)m.invoke(class);
String propertyAnotherClass = (String)m.invoke(anotherClass);
if(propertyClass != propertyAnotherClass) {
//Update attribute and attribute status.
}
} catch (Exception e) {
}
}
}
Is there another way to implement this or should I stick to lengthy methods invoking attribute per attribute and doing the checks like that?. The objects are not going to change that much and the architecture is quite modular, so there is not much update involved if the fields change but having to change a method like that worries me a little.
EDIT 1: I'm posting a working code of what I have got so far. This code is a solution for me but, tough it works, I'm using it as a last resource not because I have time to spend but because I don't want to rediscover the wheel. If I use it, I'll make a static list with the methods so I only have to fetch that list once, considering the fact that AlexR pointed out.
private static void merge(IClazz from, IClazz to) {
Method methods[] = from.getClass().getDeclaredMethods();
for(Method m : methods) {
if(m.getName().startsWith("get") && !m.getName().equals("getMetadata")) {
try {
String commonMethodAnchor = m.getName().split("get")[1];
if(!m.getReturnType().cast(m.invoke(from)).equals(m.getReturnType().cast(m.invoke(to)))) {
String setterMethodName = "set" + commonMethodAnchor;
Method setter = IClazz.class.getDeclaredMethod(setterMethodName, m.getReturnType());
setter.invoke(to, m.getReturnType().cast(m.invoke(from)));
//Updating metadata
String metadataMethodName = "set" + commonMethodAnchor + "Status";
Method metadataUpdater = IClazzMetadata.class.getDeclaredMethod(metadataMethodName, int.class);
metadataUpdater.invoke(to.getMetadata(), 1);
}
} catch (Exception e) {
}
}
}
}
metadataUpdater sets the value to 1 just to simulate the "UPDATED" flag I'm using on the real case scenario.
EDIT 3: Thanks Juan, David and AlexR for your suggestions and directions! They really pointed me to consider things I did not consider at first (I'm upvoting all your answers because all of them helped me).
After adding what AlexR sugegsted and checking jDTO and Apache Commons (finding out that in the end the general concepts are quite similar) I've decided to stick to my code instead of using other tools, since it is working given the object hierarchy and metadata structure of the solution and there are no exceptions popping up so far. The code is the one on the 2nd edit and I've placed it on a helper class that did the trick in the end.
Apache Commons Bean Utils may resolve your problem: http://commons.apache.org/beanutils/
If you want to copy all properties, try to use copyProperties: http://commons.apache.org/beanutils/v1.8.3/apidocs/src-html/org/apache/commons/beanutils/BeanUtils.html#line.134
Look an example from: http://www.avajava.com/tutorials/lessons/how-do-i-copy-properties-from-one-bean-to-another.html
FromBean fromBean = new FromBean("fromBean", "fromBeanAProp", "fromBeanBProp");
ToBean toBean = new ToBean("toBean", "toBeanBProp", "toBeanCProp");
System.out.println(ToStringBuilder.reflectionToString(fromBean));
System.out.println(ToStringBuilder.reflectionToString(toBean));
try {
System.out.println("Copying properties from fromBean to toBean");
BeanUtils.copyProperties(toBean, fromBean);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
System.out.println(ToStringBuilder.reflectionToString(fromBean));
System.out.println(ToStringBuilder.reflectionToString(toBean));
I think the best approach would be using proxy objects, either dynamic proxies or cglib enhancers or something like it, so you decorate the getters and setters and you can keep track of the changes there.
Hope it helps.
Your approach is OK, but keep in mind that getMethod() is much slower than invoke(), so if your code is performance critical you will probably want to cache the Method objects.

Smaller Methods

Following the guidelines given in "Clean Code" by Uncle Bob Martin, I'm trying to make my methods smaller.
One recommendation he gives is that methods that contain a trys should invoke other methods that don't involve the exceptional cases.
My problem is one of naming.
Usually by the time my method only contains the try expression, there's not much left and the name of the method perfectly describes what it does except for the exception.
What conventions do you use for naming the "non-exceptional" method that the exceptional one will call?
As an example, this is a method I'm looking at:
private void generateAndAttachDocumentFromTemplate(File templateFile) {
try {
File generatedDocument = generateDocumentFromTemplate(templateFile);
if (generatedDocument != null) {
attachDocument(generatedDocument, container);
attachmentsPanel.reload();
SystemControl.openDocument(generatedDocument);
}
} catch (Exception ex) {
Notifier.notifyIT(App.user().getEmail(), ex);
Dialogs.complain("Can\'t Generate Document");
}
}
I use the convention (which I think he suggests in the book) where you have methodName and tryMethodName.
anytime a method has doThisANDdoThat() is a bad method.
methods should do ONE thing and only one thing. Regardless of how "small" they are.
You could use the "Impl" convention.
private void generateAndAttachDocumentFromTemplate(File templateFile) {
try {
generateAndAttachDocumentFromTemplateImpl(File templateFile);
} catch (Exception ex) {
Notifier.notifyIT(App.user().getEmail(), ex);
Dialogs.complain("Can\'t Generate Document");
}
Some alternatives:
method > doMethod
method > method0
The "non-exceptional" methods should be private.

Categories