A more generic return - java

Looking at some code cleanup and I was wondering the best way to deal with this:
Have a class with some private variables like:
myBool1, myBool2, myBool3
myInt1, myInt2, myInt3
myString1, myString2, myString3
What's the best way to do a getter function that is generic to the return value? So if I do a call to the getter with something like:
myNewBool=<blah>.get("myBool1")
myNewString=<blah>.get("myString2")
myNewInt=<blah>.get("myInt3")
Anyone have any suggestions?

You can't really have a generic getter if you don't know what you want to get, for example :
boolean myNewBool= get("myString1");
If get returns something, but you don't really know if this something is compatible with a boolean, and terrible things could happen.
You could try this:
public <T> get(String element){
return (T) elementToGet;
}
But you would have to specify the return type when you call the get method.
String element = myObject.<String>get("element");
Here are the bad sides :
You can't work directly with primitives
You can have a lot of ClassCastException
If you misspell an attribute name you won't see it until you run it
You don't expose a nice public API, people would have to know evert possible attribute to use it, and as said above, a misspelled attribute (or an inexistant one) wouldn't be seen until runtime.
You have to know the return time and type it each time you use your method
You would have to type a really long (and smelly) code in your get method either to use each possible attribute (if you still want have some private and not accessible) or worse, use reflection to find the right attribute.
So definitively not a good idea.
What you can do instead is using the good old getters//setters and if there is a lot of them, generate them with your IDE.
Another way would be to use the project lombok.
Resources :
Project Lombok
On the same topic :
Create automatically only getters in Eclipse
Eclipse Generate All getters setters in package
Java Getters and Setters

First you should ask what would be the pros and cons of such a solution.
Pros:
One method instead of many
Cons:
Non-intuitive to the users of your class (classical getters are more common)
You cannot have an overload that only differs by a return type, therefore you will have to have methods like getBool, getInt etc.
It's slower - you have to pass the string, check for validity, do a lookup in a map...
The only advantage of your proposed solution would be not repeating the get()/set() code. However, as these methods are usually generated by your IDE and contain only a single-line command, I wouldn't see that as a big problem.
To answer your actual question - you can create a HashMap with name-attribute mapping. Alternatively, you may use Java reflection to access the attributes. The second solution is more general but also harder to write.

This is really a terrible idea. I'm not sure why creating a getter/setter for each private variable is a problem, but passing around strings that map to a variable's symbolic name would be hard to maintain and confusing. You don't need this to be generic; each variable represents a different quantity and they should be accessed as such.

It wouldn't be clean up but mess up. I'd either created 3 getter methods for the fields or redesign it completely. But calling a function, with a name of a field to return, as an argument can bring nothing good.
When you code, you must be refactoring your code for all the time you are coding. But not like this. Solution is delegating logic to another class, wrapping code into more utilizable methods or changing and simplifying domain objects...

Related

How to run methods before and after Lombok #Setter

I want some of my methods to run before and after the Lombok #Setter.
For example:
#Setter(after="save")
private String name;
This should run method called "save" after the original setter has assigned a value to the field.
So after compilation it should look like this:
public void setName(String name){
this.name = name;
this.save();
}
Maybe there is something I could do with "onMethod" parameter? Sorry, I'm not professional in annotations.
There is currently indeed no way to do this; onMethod isn't going to help either (SOURCE/DISCLAIMER: I'm a core lombok dev).
We do have some plans to add such a thing, but before you go ahead and write a PullRequest to add such a feature, discuss it first. There are various ways to go here. The primary issue is syntax.
You can't put java code in an annotation (you can put it in a string but we veto such a move; your IDE is not going to help you, it's got the wrong syntax highlighting, and so on). You can't, unfortunately, put a method reference in an annotation either. You could put a string in there that mentions a method but we don't like that either (again, wrong colouring, no IDE autocomplete support).
That leaves magic naming (you make a method called afterName), but at that point lombok saves you nearly nothing, so why not just write the setter. A second option is to have a single 'validate' method that is called after any setter and is e.g. marked by an annotation. That's more the direction we're leaning into.
There's more to consider: Sometimes you'd want to mutate the incoming value before assigning it, and the same mutation should be done in case you have a builder, or have a constructor that accepts this param, as well. Thus, we have:
Post-set actions after any setter and construction, such as save().
Pre-"setting", validate and/or mutate, after any setter and construction. For example, let's say you have a setAge() method and you want to throw an exception if someone attempts to pass a negative value. The set shouldn't even happen, so a post-set handler can't do the job (it'd be too late, the object is already in an invalid state and you'd want to avoid this). Complication: Given that we want to do this pre-setting the field, how does this method get the values, then?
Hopefully that illustrates why this feature isn't (yet) in lombok and why it's a matter of a simple PR to add it.

Java Getter Setter Codestyle

Outside of the context of beans, reflection, introspection or any other often referenced nonsense, is there an important reason that Java Getter/Setter are always notated as Type getAttribute() and void setAttribute(Type a)?
I read and wrote a lot of C++ code in recent times and when coming back to Java, I suddenly felt the urge to use Type attribute() and void attribute(Type a) as signatures for getters and setters as they somehow feel more comfortable to use all of a sudden. It reminds me of functional programming, having the attribute as a method of the object instead of having a method explicitly change or access the attribute.
The shorter style is the one I use. AFAIK Those in low level Java programming tend to use it possibly because it's more like C++, or because it's less like EJB's.
The problem with the JavaBean getter/setter style is it assumes an implementation of just setting and getting the variable, however this is not always the case.
You can use the methods the way you are comfortable with;
Type attribute() and void attribute(Type a)
The reason it is as you first example
Type getAttribute() and void setAttribute(Type a)
is used is to make it obvious what the method is to be used for. For example and new developer to a project can pick up and understand the flow of code without moving between different classes to see what that method does.
Getters & Setters are usually only one line functions. If a function is to do some data manipluation, it with usually use a descriptive name rather have a get or a set.
Summary:
Getters & Setters are mainly used for entity objects, where no data manipluation should be done, NOT saying that it can't be done.
The Java Naming Conventions state that "Methods should be verbs", which is commonly generalized by the community to "Methods should start with a verb". It is a question of consistency. You may very well use attribute, but I can guarantee you that people will confuse it. So if you expect other people to read and change you code, I strongly suggest to go for getAttribute and setAttribute. This argument is supported by Robert C. Martin in his book Clean Code (Section "Method Names"). It explicitly deals with your case.
That being said, the Java-API itself violates this rule sometimes (for example with the method size() in Collections). This is a known problem but shouldn't stop you from doing it better.

Is passing 'this' in a method call accepted practice in java

Is it good/bad/acceptable practice to pass the current object in a method call. As in:
public class Bar{
public Bar(){}
public void foo(Baz baz){
// modify some values of baz
}
}
public class Baz{
//constructor omitted
public void method(){
Bar bar = new Bar();
bar.foo(this);
}
}
Specifically, is the line bar.foo(this) acceptable?
There's nothing wrong with that. What is NOT a good practice is to do the same inside constructors, because you would give a reference to a not-yet-completely-initialized object.
There is a sort of similar post here: Java leaking this in constructor
where they give an explanation of why the latter is a bad practice.
There's no reason not to use it, this is the current instance and it's perfectly legitimate to use. In fact there's often no clean way to omit it.
So use it.
As it's hard to convince it's acceptable without example (a negative answer to such a question is always easier to argument), I just opened one of the most common java.lang classes, the String one, and of course I found instances of this use, for example
1084 // Argument is a String
1085 if (cs.equals(this))
1086 return true;
Look for (this in big "accepted" projects, you won't fail to find it.
Yes, but you should be careful about two things
Passing this when the object has not been constructed yet (i.e. in its constructor)
Passing this to a long-living object, that will keep the reference alive and will prevent the this object from being garbage collected.
It's perfectly normal and perfectly acceptable.
this stands for the current object. What you are doing is sytatically correct but i don't see a need of this if you are calling the method in the same class.
It is bad practice to pass the current object in a method call if there less complex alternatives to achieve the same behaviour.
By definition, a bidirectional association is created as soon as this is passed from one object to another.
To quote Refactoring, by Martin Fowler:
Change Bidirectional Association to Unidirectional (200)
Bidirectional associations are useful, but they carry a price. The
price is the added complexity of maintaining the two-way links and
ensuring that objects are properly created and removed. Bidirectional
associations are not natural for many programmers, so they often are a
source of errors
...
You should use bidirectional associations when you need to but not
when you don’t. As soon as you see a bidirectional association is no
longer pulling its weight, drop the unnecessary end.
So, theoretically, we should be hearing alarm bells when we find we need to pass this and try really hard to think of other ways to solve the problem at hand. There are, of course, times when, at last resort, it makes sense to do it.
Also it is often necessary to corrupt your design temporarily, doing 'bad practice things', during a longer term refactoring of your code for an overall improvement. (One step back, two steps forward).
In practice I have found my code has improved massively by avoiding bidirectional links like the plague.
Yes. you can use it.Its just common in programming to pass this.But there are pros and cons about using that.Still it is not hazardous to do so.
Just to add one more example where passing this is correct and follows good design: Visitor pattern. In Visitor design pattern, method accept(Visitor v) is typically implemented in a way it just calls v.visit(this).
Acceptable
Snippet from Oracle JAVA docs:
Within an instance method or a constructor, this is a reference to the
current object — the object whose method or constructor is being
called. You can refer to any member of the current object from within
an instance method or a constructor by using this.
Using this with a Field
The most common reason for using the this keyword is because a field
is shadowed by a method or constructor parameter.
Everything in java is passed by value. But objects are NEVER passed to the method!
When java passes an object to a method, it first makes a copy of a reference to the object, not a copy of the object itself. Hence this is pefectly used method in java. And most commonly followed usage.

Get fieldname of getter by reflection

I was never really strong in reflection and I seem to have stumped on a problem that seems trivial but doesn't turn out that way. At least for me. I have a bean with a few getters , then in a service I use Reflextion to loop over said methods and at a certain point I end up with the get method I want. I invoke the method to get the value, and now I like to know the name of the field I just asked the value from. There is it where I get stuck.
get method
public String getTest(){ return test }
invoking method by reflection
Object value = method.invoke(jsonObject, new Object[]{});
Now I like to do something like this
String fieldName = method.findTheNameOfTheField();
I find lots of examples to call the getter from the fieldname but nothing on how to do the reverse. Is this even possible without parsing the name of the method and just cutting is and get from the method ?
I invoke the method to get the value, and now I like to know the name of the field I just asked the value from.
No, you can't do this - at least not without analyzing the bytecode itself. Don't forget that the getter can contain any code. Maybe it doesn't use a field. Maybe it uses more than one field. Maybe all the properties use a map. Maybe it uses a field, but then changes the result (e.g. copies a list).
You should consider whether a change in your design would remove the need for this in the first place - I can't think of many cases where it would be a good idea.
For working with JavaBeans, the Bean Introspector makes life easier.
Tutorial
http://v1.dione.zcu.cz/java/docs/tutorial/javabeans/introspection/index.html
Examples
http://www.java2s.com/Code/Java/Development-Class/IntrospectingaBean.htm
http://www.znetdevelopment.com/blogs/2012/04/11/java-bean-introspector-and-covariantgeneric-returns/
http://www.javablogging.com/inspecting-your-java-beans/
http://softwaresalariman.blogspot.co.uk/2011/11/minimal-javabean-introspection-example.html
This uses reflection but hides much of the details like; Do I want getValue or isFlag for a getter.
The only thing you can do here is to rely on the JavaBean convention, i.e. that the method getFoo() returns the value of the field foo.
A getter may not necesarily return a field; here's a really trivial example
public getAge() {
return currentdate - birthdate;
}
The whole point of getters is that they may return a field, but they may also return something else, abstracting internal logic from those who call the method.

Declare java enum with a String array

I'm trying to declare an enum type based on data that I'm retrieving from a database. I have a method that returns a string array of all the rows in the table that I want to make into an enumerated type. Is there any way to construct an enum with an array?
This is what I tried, but from the way it looked in eclipse, it seemed like this just created a method by that name:
public enum ConditionCodes{
Condition.getDescriptions();
}
Thank you in advance!
You can't.
The values of an enum must be known at compile time. If you have anything else, then it's not an enum.
You could come rather close via an implementation that's similar to the old typesafe enums that were used before the Java language introduced support for this technique via the enum keyword. You could use those techniques but simply replace the static final fields with values read from the DB.
For your enum to be useful it has to be nailed down at compile time. Generating the enum from the database query would imply you expect to see new enum values at runtime. Even if you created a code generator to create your enum class on the fly using the database query, you wouldn't be able to reference those enum values in your code, which is the point of having them.
It's difficult to see how any compiler could support this.
The whole point of an enum is supposed to be that you get compile-time checking of the validity of your values. If, say, you declare an enum "enum MyStatusCode {FOO, BAR, PLUGH}", then in your code if you write "MyStatusCode.FOO" everything is good, but if you write "MyStatusCode.ZORK" you get a compile-time error. This protects you from mis-spelling values or getting confused about the values for one enum versus another. (I just had a problem recently where a programmer accidentally assigned a delivery method to a transaction type, thus magically changing a sale into an inventory adjustment when he meant to change a home delivery into a customer pick-up.)
But if your values are defined dynamically at run-time, how could the compiler do this? If you wrote MyStatusCode.ZORK in the above example, there is no way the compiler could know if this value will or will not be in the database at runtime. Even if you imagined a compiler smart enough to figure out how the enum was being populated and checking the database to see if that value is present in the appropriate table NOW, it would have no way of knowing if it will be there when you actually run.
In short, what you want is something very different from an enum.
If you want to get really crazy, I think annotation processing can do this. Annotation processing lets you hook the compiler and have it magically modify things when your #annotation is present.
Naturally, the values in the enum will be whatever values were available at compile time.
No, that's not possible because the enum type must be defined at compile time and what you're looking for is to dynamically create it.
Perhaps you'll be better if use a class instead.
I think here you are going to need a List or Set along with some utility methods for searching and comparison.
So here's your List
List<String> conditionCodes = new ArrayList<String>();
//Somehow get Rows or POJO Beans from database with your favorite framework
Collection<Row> dbRows = getConditionCodes();
for(Row curRow : dbRows)
conditionCodes.add(curRow.getName());
And to search
public boolean conditionExists(String name) {
return conditonCodes.contains(name);
}
public String getCondition(String name) {
return conditionCodes.get(name);
}
(of course you would probably want to use List's own methods instead of making your own)
More than you can't, you don't want to. Every enum, even Java's fairly cool enums, is code oriented.
It's exactly the same as a collection, but with an enum you tend to write duplicate code whenever you encounter it--with a collection you are more likely to write a loop.
I suggest you create a class with a private constructor and have it create the instances of itself, then provide a getInstance(String) to retrieve an instance. This is like the old typesafe enum pattern.
In the long run, however, it's better if you can manage to get enough intelligence into that class where you aren't ever differentiating on a specific instance--going from the "Enum" way of doing it:
if(myEnum.stringValue.equals("EnumTarget"))
executeCode();
To the OO way of doing it:
myEnumLikeObject.executeCode();
Moving the code you wish into the "enum"--preferably delegating directly to a contained object that is instantiated and set into the "enum" at creation time.

Categories

Resources