How to avoid forgetting to process properties? - java

Having this class
Class Test
{
static int version=1;
String A;
String B;
//constructor
//setters, getters, etc...
public void printAll(void)
{
System.out.println(A);
System.out.println(B);
}
}
After a while, we modify the Class to add a String C :
Class Test
{
static int version=2;
String A;
String B;
String C;
//constructor
//setters, getters, etc...
public void printAll(void)
{
System.out.println(A);
System.out.println(B);
//it seems somebody has forgotten to print C!!!!!!!!!
}
}
Is here some known approach to avoid this kind of bug?
Thanks

A code review should catch this issue. Aside from a code review, unit testing or debugging would normally tell you if your code is behaving how it should. If you didn't process certain properties your tests should fail because at some point a method/property/result would not be correct. Other than those things I think using reflection is way overboard.

You can use annotations to have a more structured way to use reflection, where you better control which fields will be printable:
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.FIELD})
#interface Printable { }
class Test {
#Printable String A;
#Printable String B;
#Printable String C;
public void printAll() {
for (Field field : getClass().getDeclaredFields()) {
if (field.isAnnotationPresent(Printable.class)) {
try {
System.out.println(field.get(this));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
}

I'm not sure if it's recommended, but you could get the fields of an object in the following way:
import java.lang.reflect.Field;
Field[] fields = object.getClass().getDeclaredFields();
for (int i = 0 ; i < fields.length ; i++)
System.out.println(fields[i]);

You have some code that adding, deleting or modifying in a place, affects in other. In this particular case, your function calls all properties.
You may want to something like C++, where classes doesn't have explicit properties like Java, and are emulated using either a macro or a collection.
package mycompany.myapp;
import propertiesgenerics;
Class Test
{
static int version=1;
public property<String> A;
public property<String> B;
public list< property<string> > Properties;
public Bicycle() {
public property<String> A = new property<String>();
public property<String> B = new property<String>();
Properties.add(A);
Properties.add(B);
}
//constructor
//setters, getters, etc...
public void printAll(void)
{
// iterating thru this.properties
for loop {
System.out.println(eachProperty);
} // for loop
}
}
If not a fan of misusing reflection, due to the fact that not all fields are treated like properties, and not all properties are treated like fields.

You can use org.apache.commons.lang.builder.ToStringBuilder:
public void printAll() {
System.out.println(ToStringBuilder.reflectionToString(this));
}
or
public void printAll() {
System.out.println(new ToStringBuilder(this).
append("name", name).
append("age", age).
append("smoker", smoker).
toString());
}

Sometimes the best strategy is just to put comments above your property list:
// Remember to include any new properties in the printAll method!
String A;
String B;
Apart from that, I agree with KyleM, that a code review is essential for catching issues like this.

I'm not sure I'd qualify forgetfulness as a bug. I think the best way to handle something like this is to use a source control program, so you can track changes to your files.
http://tortoisesvn.net/: this is a good one

Related

Java junit testing with assertions on objects

public class DatatypeTest {
private static final Log logger = LogFactory
.getLog(TreeConstantTest.class);
#Test
public void testDatatypeFromName()
{
Datatype d= Datatype.fromString("Profile");
assertTrue((d.toString().compareToIgnoreCase("PROFILE") == 0));
}
#Test
public void testDatatypeFromName1()
{
Datatype d = Datatype.fromString("SupportDetail");
assertTrue((d.toString().compareToIgnoreCase("SUPPORT_DETAIL") == 0 ));
}
}
When i execute the first test case it is showing failure case in green.
But when i execute the second test case it is showing me the error as java.lang.AssertionError.
I am writing the test cases for this class
public enum DocDatatype {
PROFILE("Profile"),
SUPPORT_DETAIL("SupportDetail"),
The main problem here is that the question is lacking some context. And the use-case for this DataType class is a bit strange (DataType should be the enum).
public enum DataType {
PROFILE("Profile"),
SUPPORT_DETAIL("SupportDetail");
private String value;
private DataType(String value) {
this.value = value;
}
#Override
public String toString() {
return this.value;
}
}
Your do not really need this fromString-method. Look at this class:
public class DataTypeUtil {
public static DataType fromString(String value) {
return DataType.valueOf(value.toUpperCase()); // should check for null or blank
}
}
Then you can do your test like this, note the 3'rd test-method:
public class DataTypeTest {
#Test
public void testDatatypeFromName() {
DataType d = DataTypeUtil.fromString("Profile");
assertTrue((d.toString().compareToIgnoreCase(DataType.PROFILE.toString()) == 0));
}
#Test(expected = IllegalArgumentException.class)
public void testDatatypeFromInvalidName() {
DataType d = DataTypeUtil.fromString("SupportDetail");
assertFalse((d.toString().compareToIgnoreCase(DataType.SUPPORT_DETAIL.toString()) == 0));
}
#Test
public void testDatatypeFromCorrectName() {
DataType d = DataTypeUtil.fromString("Support_Detail");
assertTrue((d.toString().compareToIgnoreCase(DataType.SUPPORT_DETAIL.toString()) == 0));
}
#Test
public void testGetValueFromEnum() throws Exception {
DataType dataType = DataType.valueOf("Profile".toUpperCase());
assertTrue(dataType == DataType.PROFILE);
}
}
Note the valueOf-method. It does exactly what your fromString-method does, and it is available to you from the enum.
Main point is that you only need your enum and DataType is your best bet.
Hope this clarifies your problem somehow :)
Edit:
If I should guess your use-case, you have a document which has a certain format or type. Why not create a Document class with DataType as an enum field on the object?
Regards,
Thomas
What you need is the ability to see the actual value.
You can go in with a debugger, but that's not a good solution: what if your test is run by an automated system?
You need to change your assertion into something that will provide more information.
Please look at this question for JUnit way to assert equalsIgnoreCase.
Another way is to provide a failure message:
assertTrue("Unexpected result: + d.toString(), "SUPPORT_DETAIL".compareToIgnoreCase(d.toString()) == 0 ));

How can I implement a lazy-evaluated stateful class with internal dependencies in Java?

I'm writing a financial calculation class which will have a number of setter function inputs, some private intermediate values and a number of getter functions as outputs.
The private intermediate values are only dependant on the input values.
The output values (accessed by public getters) are only dependant on the inputs and the intermediate values.
Ultimately you could draw the whole thing as a somewhat tangled acyclic directed graph whith a bunch of inputs on one side, eventually flowing to a bunch of outputs on the right hand side.
What's the best way to implement this class. I have some spesific requirements:
Where possible, lazy evaluate. When an input changes we have now way of knowing what outputs might be required.
The class has to be easy to re-design, so some kind of declarative model would epreferred.
Ideally I'd like to be able to say that C depends on A and B. If C were requested after either A or B had changed then it would know tht C needed to be re-calculated, otherwise C would never need to be refreshed.
IIs there a Java pattern that might help me cleanly implement this kind of calculator?
You can build a solution by creating a future value that is recalculable.
public class Computation<T> {
private T value;
private Set<Computation<?>> usedBy;
public T getValue(Computation<?> getter) {
if (usedBy == null) {
// value was not computed
value = compute();
usedBy = new HashSet();
}
if (getter != null) {
// add a dependency
usedBy.add(getter);
}
return value;
}
protected T compute() {
// override when needed a lazily-computed value
return null;
}
public void setValue(T value) {
// invalidate this value
invalidate();
// set the new value
this.value = value;
usedBy = new HashSet();
}
public void invalidate() {
if (usedBy != null) {
for (Computation<?> c : usedBy) {
c.invalidate();
}
usedBy = null;
}
value = null;
}
}
public class Business {
private Computation<Integer> a = new Computation<Integer>();
private Computation<Integer> b = new Computation<Integer>();
private Computation<Integer> c = new Computation<Integer>() {
public Integer compute() {
return a.getValue(this) + b.getValue(this);
}
};
public void setA(int v) {
a.setValue(v);
}
public void setB(int v) {
b.setValue(v);
}
public int getC() {
return c.getValue(null);
}
}
It is completely lazy and figures out the dependencies.
You can use a pattern like this.
double[] inputs = { ... }
double[] previousInputs = { Double.NaN, etc }; // NaN is never equal.
double[] outputs =
public void update() {
if (!Arrays.equals(inputs, previousInputs)) {
recalculate(inputs, outputs);
copyTo(inputs, previousInputs);
}
}
Seems like you have some sort of real-time stream processing problem.
Take a look at twitter storm. Even if you decide not to use it you can borrow some concepts explained at tutorial page.
Personally I agree with Peter but for arguments sake I have two other answers. I would recommend looking at a rules engine (e.g. Drools) for implementing flexible business logic like this. They are designed so that the rules for updates between variables are easy to set and change at will. They should also be fairly performant.
Then, for the DYI-er, here is a Spring inspired version. The biggest drawback is that you get your dependencies as a list. You could easily use a HashMap but then you'd lose your syntax-safety.
public abstract class Variable<T> {
private T currentValue;
private List<Variable<?>> dependencies = new ArrayList<Variable<?>>();
private List<Variable<?>> upstream = new ArrayList<Variable<?>>();
public T get() {
return currentValue;
}
public void set(T newValue) {
currentValue = newValue;
updateUpstream();
}
public abstract T recalculateValue(List<Variable<?>> dependencies);
private void update() {
set(recalculateValue());
}
private void updateUpstream() {
for(Variable<?> variable : upstream) {
variable.update();
}
}
private void addUpstream(Variable<?> variable) {
upstream.add(variable);
}
public void setDependencies(List<Variable<?>> dependencies) {
this.dependencies = dependencies;
for(Variable<?> variable) {
variable.addUpstream(this);
}
}
}
The corresponding applicationContext.xml would look like:
<bean id="A" class="com.app.AVariable"/>
<bean id="B" class="com.app.BVariable"/>
<bean id="C" class="com.app.CVariable">
<property name="dependencies">
<list>
<ref bean="A"/>
<ref bean="B"/>
</list>
</property>
</bean>
For extra credit you could implement a bean post-processor to calculate and set the dependencies automatically based on annotations. For example:
public class CVariable extends Variable<Integer> {
private AVariable a;
private BVariable b;
#Dependency
public void setA(AVariable a) {
this.a = a;
}
#Dependency
public void setB(BVariable b) {
this.b = b;
}
//If you were going this route you wouldn't need the list of dependencies
public Integer recalculateValue() {
return a.get() + b.get();
}
}

Java and avoid if statements for objects with similar methods

I have 2 classes e.g. A and B.
These classes have a couple of getter/setter methods with the same name.
Now in the code I do the following:
if(obj.getClassName().equals(A.class.getName())){
A a = (A) obj;
String result = a.getInfo();
}
else if(obj.getClassName().equals(B.class.getName())){
B a = (B) obj;
String result = a.getInfo();
}
I was wondering if there is a way to call the getInfo avoiding the if statements.
Note: I can not refactor the classes to use inheritence or something else.
I was just interested if there is a trick in java to avoid the if statements.
Unless you want to use reflection, no. Java treats two types which happen to declare the same method (getInfo()) as entirely separate, with entirely separate methods.
If you've got commonality, you should be using a common superclass or a common interface that both of them inherit. You've tagged the question "design-patterns" - the pattern is to use the tools that the language provides to show commonality.
As Eng.Fouad shows, using instanceof is simpler anyway - and better, as it means your code will still work with subclasses of A or B.
You can isolate this ugliness, of course, by putting it in a single place - either with a facade class which can be constructed from either an A or a B, or by having a single method which performs this check, and then calling that from multiple places.
If you can't use inheritance and want to avoid if statements (even using instanceof)... well... the best you can do is wrap the check, cast and call in a function to avoid code duplication... otherwise there's no way to do this.
You need reflection. here is my complete example.
Class A
package a;
public class A {
String info;
public String getInfo() {
System.out.println("A getInfo");
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
Class B
package a;
public class B {
String info;
public String getInfo() {
System.out.println("B getInfo");
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
Test Class
package a;
import java.lang.reflect.Method;
public class TestAB {
public static void main(String[] args) {
A a= new A();
doSth(a);
}
private static void doSth(Object obj) {
Class c = obj.getClass();
Method m;
try {
m = c.getMethod("getInfo", new Class[] { });
String result = (String) m.invoke(obj);
} catch (Exception e) {
e.printStackTrace();
}
}
}
See this line :
Class c = obj.getClass();
and
m = c.getMethod("getInfo", new Class[] { });
and
String result = (String) m.invoke(obj);
There is no if statements
If obj is declared as either A or B, you can use overloaded methods. (A good argument for type safety.) Here's a test that illustrates this:
import static org.junit.Assert.*;
import org.junit.Test;
public class FooTest {
class A {
public String getInfo() {
return "A";
}
}
class B {
public String getInfo() {
return "B";
}
}
public String doBarFor(A a) {
return a.getInfo();
}
public String doBarFor(B b) {
return b.getInfo();
}
public String doBarFor(Object obj) {
throw new UnsupportedOperationException();
}
#Test
public void shouldDoBarForA() {
A a = new A();
assertEquals("A", doBarFor(a));
}
#Test
public void shouldDoBarForB() {
B b = new B();
assertEquals("B", doBarFor(b));
}
#Test(expected = UnsupportedOperationException.class)
public void shouldFailIfDeclaredAsObject() {
Object a = new A();
assertEquals("A", doBarFor(a)); // exception thrown
}
}
How about:
String result = null;
if(obj instanceof A)
{
result = ((A) obj).getInfo();
}
else if(obj instanceof B)
{
result = ((B) obj).getInfo();
}
Refer to : this tutorial if this is what you were trying to achieve.
If obj is an Object, you'll need to check. If you don't want to use an if-statement, you can try just casting and catch the exception:
String result = null;
try {
result = ((A)obj).getInfo();
}
catch(ClassCastException e1) {
try {
result = ((B)obj).getInfo();
}
catch(ClassCastException e2) {
// do something else
}
}
Another thing you can do is make both classes implement an Interface then check for just that Interface, something like:
public interface HasInfo
{
public String getInfo();
}
Then add implements HasInfo in the class definition for A and B. Then you can just check (or cast) to HasInfo.
In Java you can use a dot as a scope resolution operator with static methods. Try something like this:
String a_info = A.getInfo();
String b_info = B.getInfo();
With objects, if two interfaces really have the same method with the same parameters and the same return type, why must they be treated differently? Take a look here for some more insight into the problem.
Good luck.

How to have a method have different input types java

I have a program on my computer that simulates a server on the internet and the fake server needs to be able to send multiple data types to some classes. Like for instance at one point of the program the server needs to send an int to a class then convert that int to a string and send it to another.
Basically what I am asking is if a method can have multiple data types for an input(Does this make sense? if not ill try to explain better). Is there any way to do this without creating many different methods?
Edit: Also is there a way to tell the difference between the types passed in (to prevent errors)
You can have a method which takes Object which is any type. In Java 5.0 and later primitives will be auto-boxed and passed as an object as well.
void method(Object o);
can be called using
method(1);
method("hello world");
method(new MyClass());
method(null);
If I understand correctly, you're asking if a method foo() can have multiple different inputs for its parameters
That way foo(Integer i) and foo(String s) are encased in the same method.
The answer: yes, but it's not pretty
foo(Object o)
Is your method declaration
Now you need to sort out the different types of possibilities
if(o instanceof Integer){
stuff();
} else if (o instanceof String){
moreStuff();
}
Just chain those else/if statements for the desired result.
What you want are Generic methods or classes.
to check what type an object is you'll have to use the 'instanceof' method
you can either make an entire class generic or just a single method, an example of a generic class:
package javahowto;
public class Member<T> {
private T id;
public Member(T id) {
this.id = id;
}
public T getId() {
return id;
}
public void setId(T id) {
this.id = id;
}
public static void main(String[] args) {
Member<String> mString = new Member<String>("id1");
mString.setId("id2");
System.out.printf("id after setting id: %s%n", mString.getId());
//output: id after setting id: id2
Member<Integer> mInteger = new Member<Integer>(1);
mInteger.setId(2);
System.out.printf("id after setting id: %d%n", mInteger.getId());
//output: id after setting id: 2
}
Now you now what to look for I'm sure you'll find the best solution to your problem.
check out:
http://download.oracle.com/javase/tutorial/java/generics/index.html
http://en.wikipedia.org/wiki/Generics_in_Java
...
Well I have also wondered and wrote below block. I think instanceof better but I tried getclass.
public static void main(String[] args){
System.out.println(method("This is a test"));
}
private static String method(Object o){
System.out.println(o.toString());
String status = "";
String className;
String[] oList = {"Double","Integer","String","Double","Float","Byte","Short","Long","Character","Boolean" };
for(int i = 0;i<oList.length;i++){
className = "java.lang." + oList[i];
Class testClass;
try {
testClass = Class.forName(className);
if(o.getClass().equals(testClass)){
status = "Your object is " + oList[i];
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return status;
}
You could use the "hashed adapter" pattern.
Public interface Adapter {
Public void handle(object o);
}
Public class StringAdapter implements Adapter {
Public void handle(String st) { // stuff ...
}
Public class IntegerAdapter implements Adapter {
Public void handle(Integer intgr) { // stuff ...
}
Private static final Map adapters = new HashMap();
Adapters.put(string.class, new stringAdapter());
Adapters.put(Integer.class, new IntegerAdapter());
Public void handleMe(Object o) {
Adapters.get(o.getClass()).handle(o);
}
Ive always liked this more than the ol' cascade of ifs and else's.
On my iPad so sorry about formatting and terseness and speellling.

Dynamically return a list of all class variable values in Java

I am creating a helper class in parsing XML elements, so the developer do not need to know the exact name and capitalization of the XML fields.
private static class TagNames{
public static String RESOURCE_ID = "ResourceId";
public static String RESOURCE_NAME = "ResourceName";
public static String RESOURCE_PRICE = "ResourcePrice";
}
This makes it easier to do things like:
someXMLParser.getValueByTagName(TagNames.RESOURCE_ID);
My question is this. If I want to iterate over all the fields declared in class TagNames, how do I do that? Pseudocode:
For tag in TagNames:
someXMLParser.getValueByTagName(tag)
I know I will probably have to restructure all of this. But I can't figure out a way to make the names easily accessible as well as iterable, without any duplication.
Any suggestions?
You're literally asking for a solution based on reflection, but I think a Java Enum may be a better choice in this case. Building on Frederick's example:
public class EnumTest {
public enum Tags {
RESOURCE_ID("ResourceId"),
REOURCE_NAME("ResourceName"),
RESOURCE_PRICE("ResourcePrice");
private final String tagName;
Tags(String tagName) {
this.tagName = tagName;
}
public String getTagName() {
return tagName;
}
}
public static void main(String[] args) {
for(Tags tag : Tags.values()) {
System.out.println("const:" + tag.name()
+ " tagName:" + tag.getTagName());
}
// API user might do e.g.:
// document.getValueForTag(Tags.REOURCE_NAME);
}
}
Although I agree that you should probably use enums or ResourceBundles, here's a solution to your actual question. A method that generates a Map name -> value from all public constants in a given class (the only thing that's missing should be try / catch or throws)
public static Map<String, Object> getConstantValues(Class<?> clazz){
Map<String, Object> constantValues = new LinkedHashMap<String, Object>();
for(Field field : clazz.getDeclaredFields()){
int modifiers = field.getModifiers();
if(Modifiers.isPublic(mod)
&& Modifiers.isStatic(mod) && Modifiers.isFinal(mod)){
constantValues.put(field.getName(), field.get(null));
}
}
return constantValues;
}
You may want to consider using a ResourceBundle instead of a class to store the tag names. May require a little bit of reworking of your code but it will be easier to produce a list of tags compared to what you are doing now, and adding a new tag won't require much work other then adding a line to the properties file.
You can do this quite easily using enum and an accompanying array:
public class Main {
public enum TagName { RESOURCE_ID, REOURCE_NAME, RESOURCE_PRICE }
private static String[] tags = {"ResourceID", "ResourceName", "ResourcePrice"};
public static String getValueByTagName(TagName tag) {
return tags[tag.ordinal()];
}
public static void main(String[] args) {
System.out.println("Calling by getValueByTagName:");
System.out.println(getValueByTagName(TagName.RESOURCE_ID));
System.out.println("Calling TagName.values() for loop:");
for (TagName t : TagName.values()) {
System.out.println(getValueByTagName(t));
}
}
}
Using an enum is a good fit, especially if you use a custom constructor and the built in "values" method:
public class Main {
public static enum TagName {
RESOURCE_ID("ResourceId"),
RESOURCE_NAME("ResourceName"),
RESOURCE_PRICE("ResourcePrice"),
;
private String s;
private TagName(String s) { this.s = s; }
public String toString() { return this.s; }
public static String[] strings() {
List<String> ss = new ArrayList<String>();
for (TagName tagName : TagName.values()) {
ss.add(tagName.toString());
}
return ss.toArray(new String[ss.size()]);
}
}
public static void main(String[] args) {
// Use TagName.values() for the enums, or for strings...
for (String s : TagName.strings()) {
System.out.println(s);
}
}
}
This way you can simply add new tags and they'll automatically get picked up by the "strings" method; for extra performance you could compute that string array just once, statically, since you can't change the set of enums dynamically. You could get even fancier by auto-generating the tag strings from their constant values, if they are really normalized...

Categories