Java global isEmpty() method - java

I have an application which uses code that produces various types of objects and data structures, returning them as Object instances, and would like a generic way of establishing whether any of those objects is "empty" (or null).
(This is not a matter of design, or of whether such a method should be used, but a question of optimizing the solution to an existing requirement.)
So, here is a simple go:
public static boolean isEmpty(Object content)
{
if (content == null)
{
return true;
}
else if (content instanceof CharSequence)
{
return (((CharSequence)content).length() == 0);
}
else if (content instanceof Collection<?>)
{
return ((Collection<?>)content).isEmpty();
}
else if (content instanceof Object[])
{
return (((Object[])content).length == 0);
}
else // Use reflection (an exaggeration, for demo purposes)
{
try
{
Method isEmpty = content.getClass().
getDeclaredMethod("isEmpty", (Class<?>[])null);
if (isEmpty != null)
{
Object result = isEmpty.invoke(content, (Object[])null);
if (result instanceof Boolean)
{
return (Boolean)result;
}
}
}
catch (Exception e)
{
}
}
return false;
}
Any ideas for potential improvements, in terms of either performance, or coverage?
For instance, reflection could be also used to establish whether the object has a length() or size() method, invoke it and see if the result is 0. (In reality, reflection is probably too much, but I am including it here for completeness.)
Is there a top-level class very commonly used, which has a length() or size() method, instead of the isEmpty() method, to include in the above case, similarly to Collection that has isEmpty()?

Instead of the ugly instanceofs, split up the method into several methods with the same name but different args. e.g.
static boolean isEmpty(Object[] array)
static boolean isEmpty(Collection collection)
static boolean isEmpty(CharSequence cs)
Instead of reflection, if you really want your own interface for special objects, declare that interface, and then, for consistency with the above, offer the static utility
static boolean isEmpty(IMayBeEmpty imbe);

This method would at least solve your problem of the generic isEmpty(Object) problem. However, you don't get compile time safety with this, and calling it without the method existing for the exact type requested will yield a runtime error. Note the "MethodUtils" class is from apache commons-beanutils, though you could easily use reflection directly, but for the sake of simplicity, i'm using beanutils here.
The "invokeExactcMethod" method looks for a static method in the given class with the given name that has the compatible parameters of the object array being passed. So if the runtime type of the object is ArrayList, it would look for isEmpty(ArrayList) then isEmpty(AbstractList) then isEmpty(List). It then invokes that method if it can find it, otherwise it throws a NoSuchMethodException.
public class MyUtility {
static boolean isEmpty(Object object) {
if (object == null) {
return true;
}
else {
try {
return MethodUtils.invokeStaticMethod(
MyUtility.class, "isEmpty", new Object[]{object});
}
catch (NoSuchMethodException e) {
throw new IllegalArgumentException(e);
}
catch (IllegalAccessException e) {
throw new IllegalArgumentException(e);
}
catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
}
}
the "invokeExactStaticMethod" is more deterministic and doesn't use assignment compatibility, but exact signature matching. That means isEmpty(List) would never match anything because you can't construct anything of that type.

Related

Best pattern to create a wrapper Constructor

The problem is the following. Given a class GenericConfig which encapsulates a Map<String, Object> to contain several configurations, a class SpecificConfig is desired to have getters to retrieve specific map values.
For example, I want to avoid testing that GenericConfig.getProperties().get(KEY_OF_PROPERTY); is null and getting the value, with the burden of memorizing the key value in the calling method. I want to create a SpecificConfig that is created only if the key is present and that has a getProperty() method.
Example of what I want to avoid:
private final static String KEY_OF_PROPERTY = "key.for.my.value";
public void process(List<GenericConfig> configs) {
for(GenericConfig config: configs) {
String value = config.getProperties().get(KEY_OF_PROPERTY);
if (value != null) {
// do something
}
}
}
This is my attempt:
public final class SpecificConfig extends GenericConfig {
public SpecificConfig(GenericConfig from) {
if(from.getProperties().get(KEY_OF_PROPERTY) != null) {
this.properties = from.getProperties();
} else {
throw new ThisIsNotTheConfigIWant();
}
}
public String getProperty() {
return (String) this.properties.get(KEY_OF_PROPERTY);
}
}
So I can do the following:
public void process(List<GenericConfig> configs) {
for(GenericConfig config: configs) {
try {
SpecificConfig c = new SpecificConfig(config);
// now i can be sure that c is of the required type
// do stuff related to that type
} catch (ThisIsNotTheConfigIWant) { /* ignore this config */ }
}
}
Is throwing a checked exception in the constructor a bad thing in OOP? Does a pattern to solve this problem exist? Is it viable to instantiate null in the constructor instead of throwing an exception.
When calling the constructor it must return an instance of the class, never null. But if you want it to be possible to be null, use a static factory method instead:
public SpecificConfig maybeCreateFrom(GenericConfig c) {
if (<matches>) {
return SpecificConfig(c);
} else {
return null;
}
}
Then on the for-loop you can check for not-null. I think that is generally better than using clunky exceptions for control-flow handling. Though I suspect this is still not the best architecture for you.
Does the class GenericConfig holds a single config or a Map of configs? I would consider just creating methods to fetch configs with the existing keys + doing any null checks. Then you can just call getConfigX() or something.

Java reflection inside stream's filter

I have an Java POJO:
public class Event {
private String id;
private String name;
private Long time;
}
A simple filtering method I created is:
public static List<Event> simpleFilter(List<Event> eventList, String value) {
return eventList.stream().filter(Event -> Event.getName().equals(value)).collect(Collectors.toList());
}
Now my task is to create a generic method instead of simpleFilter which can be applied for any Java POJO object and any of its fields. For example, if in future there is a new Java object Employee and we want to filter on its String field employeeDepartment, we can use same generic filter method by passing the List of Java object (List<Employee>, Class type Employee.class, which field (getEmployeeDepartment) and what value ("Computer") we want to filter on.
I created a method definition:
public static <T> List<T> genericStringFilterOnList(List<T> list, Class<T> c, String methodName, String value) {
}
Caller looks like:
//events is List<Event>
//getName is the method in Event on which I want to filter
//e2 is value which I want to filter
genericStringFilterOnList(events, Event.class, "getName", "e2")
My implementation is:
public static <T> List<T> genericStringFilterOnList(List<T> list, Class<T> c, String methodName, String value) {
return list.stream().filter(m -> {
try {
return c.getMethod(methodName, null).invoke(c).equals(value);
} catch (IllegalAccessException e) {
} catch (IllegalArgumentException e) {
} catch (InvocationTargetException e) {
} catch (NoSuchMethodException e) {
} catch (SecurityException e) {
}
return false;
}).collect(Collectors.toList());
}
All these catch were generated by IDE because of checked exception.
This doesn't seem to working because it is returning back an empty list.
What I am trying to do here is - Using the class type (which is Event.class), I am getting method name using reflection and then invoking that method and then invoke which is basically calling getName() method of Event class and then equals. I also tried this -
return c.getMethod(methodName, null).invoke(c.newInstance()).equals(value);
But with this I am getting NPE on this
}).collect(Collectors.toList());
Can you please help me in creating a generic method which can be called for a List of any POJO and a filter can be applied on any of its String type methods?
The invocation should happen on the steamed item, not on the class itself. The method Method::invoke(Object obj, Object... args) has two parameters:
obj - the object the underlying method is invoked from
args - the arguments used for the method call
Change the line:
return c.getMethod(methodName, null).invoke(c).equals(value);
.. to:
return c.getMethod(methodName, null).invoke(m).equals(value);
The confusion comes from the one-lettered variable names (see the solution below).
The whole solution shall be simplified. You don't want to extract the very same Method through reflection for the each object present in the stream pipeline. Extract the Method first and reuse it:
static <T> List<T> genericStringFilterOnList(List<T> list, Class<T> clazz, String method, String value) {
try {
// reflection invoked just once
Method method = clazz.getMethod(method, null);
// now streaming of the n items
return list.stream().filter(item -> {
try {
return value.equals(method.invoke(item));
} catch (IllegalAccessException | InvocationTargetException e) {}
return false;
}).collect(Collectors.toList());
} catch (NoSuchMethodException e) {}
return Collections.emptyList();
}
(Out of scope of this question): Note there is a higher probability that the invoked method returns null than the passed value is, therefore I'd go for value.equals(method.invoke(item)). Maybe, you want to add some additional comparison condition when both values are null to be compared.

Is it right way for handling exceptions using Apache ExceptionUtils.getRootCause?

Is it possible, that below condition in "My code" will be fulfilled(true)? I belive that no, beacuse getRootCause returns object casted to Throwable. So it should check, if Throwable is a subtype of MyOwnException, which is not true. So, in general, it is wrong way to use getRootCause to handle exceptions, is not it?
MyOwnException part
public class MyOwnException extends Exception {
// ....
}
Apache's ExceptionUtils.getRootCause
public static Throwable getRootCause(Throwable throwable) {
List list = getThrowableList(throwable);
return (list.size() < 2 ? null : (Throwable)list.get(list.size() - 1));
}
My code
try {
// do something
} catch (Exception e) {
try {
Throwable exc = ExceptionUtils.getRootCause(e);
if (exc instanceof MyOwnException) {
// do something
}
}
}
instanceof will check against the actual run-time type of an object instance. It does not matter what the declared compile-time type of the variable that holds the object is.
So your condition works: If the root cause is a MyOwnException then your if block's body will execute.

Rete object not freeing Values after reset

I am using Jess together with a FixThreadPool to create several Rete engines that can be used to evaluate the performance of a system in a parallel mode. Each Rete engine runs independently from the others and takes as an input a Java object containing the design of the system and outputs another Java object that contains its performance metrics.
Before evaluating each system, I reset the Rete engines to their original state. However, as my program runs the RAM memory keeps piling up, with more and more jess.Value objects being stored.
This is the class that I use to interface Jess with Java:
public class Variant {
private final Object value;
private final String type;
public Variant(Object value) {
this.value = cast2JavaObject(value);
this.type = (this.value instanceof List) ? "multislot" : "slot";
}
public Object getValue() {
return value;
}
public String getType() {
return type;
}
private Object cast2JavaObject(Object value) {
try {
if (value instanceof Value) {
return castJessValue((Value) value);
} else {
return value;
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
return null;
}
}
private synchronized Object castJessValue(Value value) throws Exception {
if (value.type() == RU.LIST) {
List list = new ArrayList<Object>();
list.addAll(Arrays.asList((Object[]) RU.valueToObject(Object.class, value, null)));
return list;
} else {
return RU.valueToObject(Object.class, value, null);
}
}
public Value toJessValue() throws Exception {
Object val;
if (value instanceof List) {
val = ((List) value).toArray();
} else {
val = value;
}
return RU.objectToValue(val.getClass(), val);
}
}
Is it possible that the Object contained within the Variant is pointing to the contents of a jess.Value and therefore they are not being collected by the GC when I call rete.reset()?
I think that this would be possible if the object passed in the constructor (be it a jess.Value or a plain POJO) references one or more jess.Value's. Neither your cast2JavaObject nor RU.valueToObject are recursive + introspective.
However, what if there were jess.Value objects contained? They are decorations for Java objects, and even if they were unwrapped the heap would be piling up with the bared objects alone, just slower.
If you use store/fetch I'd also call clearStorage in addition to reset.
I suggest an experiment to narrow the OOM problem down. Rather than reset, recreate the Rete object. If the problem persists, I daresay it is in some other nook or cranny of your application.

Dynamic null check [duplicate]

This question already has answers here:
Check chains of "get" calls for null
(11 answers)
Closed 3 years ago.
I intend to make a common dynamic null check function on any object before doing some work on it.
For example:
Class A{
B b;
// with getters and setters of b
}
class B{
C c;
//with getters and setters of c
}
class C{
BigInteger d;
//with getters and setters of d
}
now, I want to check whether objA.getB().getC().getD() returns some value or throws NullPointerException?
By common I mean I can pass any kind of object to it, something like below function
CheckNull.checkingDynamicNull( "objA.getB().getC().getD()" )
will return me true or false depending on the case.
Any ideas?
Unfortunately it is not possible to pass a funktion into a method in Java (yet, Java 8 will). Also, if you pass the variable name as String this wont work, since the recieving method has no way of knowing what Object is mapped to that variable (if you ignore reflection but even with that you are screwed if its a local variable).
Another way would be to do something like this
boolean nullCheck(Object obj, String Methods)
and then parse the String to Methods and invoke them on the object. But that wont work if you have Methods with arguments.
In short: It's more trouble then it's worth
In the most cases you want to have something like this
if(object == null){
//error behavior
}
This assumes that you want to throw a certain Exception, have means to get a value for the null object elswhere or want to do something before you throw an exception.
If you simply want to throw an Exception (that is not a NullPointerException)
assert object != null
What about this:
public boolean checkingDynamicNull(A objA) {
try {
objA.getB().getC().getD().toString();
} catch(NullPointerException npe) {
return true;
}
return false;
}
To know if a statement would return null, you would have to execute it first. Even if you somehow manage to execute the statement given in String to your method, it would be no different than just running it and checking whether the result is null, or catching the NullPointerException.
You are looking for something that will be part of Java 8 (or 9 or 10?) soon. Cf. http://viralpatel.net/blogs/null-safe-type-java-7-nullpointerexception/
With reflection it could be something like that:
nullCheck(objA, "getB", "getC", "getD" );
public static boolean nullCheck(Object obj, String... methods) {
Object o = obj;
Class<?> clazz = obj.getClass();
Method method = null;
try {
for( String name : methods ) {
method = clazz.getMethod( name, null );
o = method.invoke( o, null );
clazz = method.getReturnType();
}
} catch( NullPointerException e ) {
System.err.println(clazz.getSimpleName()+"(null)."+method.getName());
return false;
} catch( NoSuchMethodException e ) {
e.printStackTrace();
} catch( SecurityException e ) {
e.printStackTrace();
} catch( IllegalAccessException e ) {
e.printStackTrace();
} catch( IllegalArgumentException e ) {
e.printStackTrace();
} catch( InvocationTargetException e ) {
e.printStackTrace();
}
return true;
}
System.out.println(nullCheck(GraphicsEnvironment.getLocalGraphicsEnvironment(), "getDefaultScreenDevice", "getDisplayMode", "toString"));
System.out.println(nullCheck(GraphicsEnvironment.getLocalGraphicsEnvironment(), "getDefaultScreenDevice", "getFullScreenWindow", "doLayout"));
brings
true
false
'Window(null).doLayout'
you can achieve this by using reflection, here is your method:
public boolean dynamicNullCheck(Object o, String path) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
Object object= o;
for (String element : path.split("\\."))
{
Field field = object.getClass().getDeclaredField(element);
field.setAccessible(true);
Object fieldVal = field.get(object);
if (fieldVal!=null)
{
field.setAccessible(true);
object = fieldVal;
}
else
{
return true;
}
}
return false;
}
use it by giving your root element and path to each object, ie dynamicNullCheck(objA,"b.c.d")

Categories