java :Can I observe value change on object by watching hashcode? - java

I have a Model class DOModel :
package amarsoft.dbmp.credit.web.model;
import ejp.annotations.ConcreteTableInheritance;
import amarsoft.rcp.base.databinding.BindableModel;
#ConcreteTableInheritance
public class DOModel extends BindableModel {
/**
* 编号
*/
private String id;
/**
* 名称
*/
private String name;
/**
* 模板类型,没有太大意义
*/
private String type;
/**
* 模板参数
*/
private String args;
private String updateTable;
private String updateWhere;
private String fromClause;
private String whereClause;
private String groupClause;
private String orderClause;
public String getId() {
return id;
}
public void setId(String id) {
this.firePropertyChange("id", this.id, this.id = id);
}
public String getName() {
return name;
}
public void setName(String name) {
this.firePropertyChange("name", this.name, this.name = name);
}
public String getType() {
return type;
}
public void setType(String type) {
this.firePropertyChange("type", this.type, this.type = type);
}
public String getArgs() {
return args;
}
public void setArgs(String args) {
this.firePropertyChange("args", this.args, this.args = args);
}
public String getUpdateTable() {
return updateTable;
}
public void setUpdateTable(String updateTable) {
this.firePropertyChange("updateTable", this.updateTable, this.updateTable = updateTable);
}
public String getDoUpdateWhere() {
return updateWhere;
}
public void setDoUpdateWhere(String doUpdateWhere) {
this.firePropertyChange("updateWhere", this.updateWhere, this.updateWhere = doUpdateWhere);
}
public String getFromClause() {
return fromClause;
}
public void setFromClause(String fromClause) {
this.firePropertyChange("fromClause", this.fromClause, this.fromClause = fromClause);
}
public String getWhereClause() {
return whereClause;
}
public void setWhereClause(String whereClause) {
this.firePropertyChange("whereClause", this.whereClause, this.whereClause = whereClause);
}
public String getGroupClause() {
return groupClause;
}
public void setGroupClause(String groupClause) {
this.firePropertyChange("groupClause", this.groupClause, this.groupClause = groupClause);
}
public String getOrderClause() {
return orderClause;
}
public void setOrderClause(String orderClause) {
this.firePropertyChange("orderClause", this.orderClause, this.orderClause = orderClause);
}
#Override
public String toString() {
return "DOModel [id=" + id + ", name=" + name + "]";
}
#Override
public int dataValueHashCode() {
int code = 0;
if (id != null) {
code += id.hashCode();
}
if(name != null){
code += name.hashCode();
}
if(type != null){
code += type.hashCode();
}
if(args != null){
code += args.hashCode();
}
if(updateTable != null){
code += updateTable.hashCode();
}
if(updateWhere != null){
code += updateWhere.hashCode();
}
if(fromClause != null){
code += fromClause.hashCode();
}
if(whereClause != null){
code += whereClause.hashCode();
}
if(groupClause != null){
code += groupClause.hashCode();
}
if(orderClause != null){
code += orderClause.hashCode();
}
return code;
}
}
this class is used in ORM, when one or more property of DOModel's instance is changed, I need to persist the DOModel's instance back to database.
so there is a problem for me: how can I know a DOModel instance object is modified compared to a specific time ?
please notice the method dataValueHashCode, I use a combination of the hash code of all the properties to measure if a model is changed.the basic flow is:
1.load the a DOModel object from database
2.call dataValueHashCode method and cache it
3.(optional)modify property values
4.when need to save the object back to database, call dataValueHashCode method again
and compare it to the cached one
5.if match, no change. if not match, save it back to database.
It seems that works right now, but as a java newbie, I am worrying there is potential problems. so before I go further, I want to prove my way will not lead me to a wrong place.
As a Chinese, my English is not good enough. if you have problem to understand what I am talking about, please post comment, I will try my best to edit this question.
thanks a lot!

There is something potentially wrong with that approach: two different objects may have the same hashCode value (the contract for hashcode is only that if a.equals(b) is true, then a.hashCode == b.hashCode, theoretically, all hashCodes could return 1 they would still be valid albeit inefficient)
So you need to come up with a cryptographic hash of yours that doesn't use hashcode, if you want to be absolutely certain it reflects your object change. I suggest using MD5 encryption, which (almost) uniquely identifies a string. It's not completely collision-resistant (means theoretically, there are multiple strings with the same output), but in practice, it's good enough.
http://en.wikipedia.org/wiki/MD5
It's quite easy to do in Java:
final MessageDigest messageDigest = MessageDigest.getInstance("MD5");
final byte[] data = stringToConvert.getBytes();
messageDigest.update(data,0,data.length);
final BigInteger hash = new BigInteger(1,messageDigest.digest());
return String.format("%1$032X", hash);

That sounds like you're relying on "equal hash codes imply equal objects" which is not safe to rely on.
Assuming a proper implementation of hashCode, you should be able to rely on "different hash codes mean unequal objects" - but the reverse is not true.
In particular, an implementation of:
#Override public int hashCode() {
return 0;
}
is always valid. Sucky, but valid.

If you want to be sure that there is no change you have to compare the contents of the attributes rather than the hash code. For that you should implement the equals method. The problem with the hash code is that though unlikely it can be the same value for different property values.

This is not the way to override hashCode(). Joshua Bloch tells you the correct way to do it in chapter 3 of his "Effective Java".

It seems that works right now, but as a Java newbie, I am worrying there is potential problems.
It's not a safe approach: A change in an object, does not guarantee that the objects hash code changes.
Keep in mind that a hash code is simply an int. If your object have more than 232 states (as in your case) you are bound to have hash collisions.
A few more pointers regarding your code:
When overriding hashCode, you need to also override equals.
Your hashCode implementation is not very good (it doesn't provide a very good distribution)

Related

Appropriate Java design pattern to avoid method duplication

I have this scenario. I started working with a system that 'process' documents. The problem is, it seems to be the typical scenario where it started small, and went getting bigger and bigger constructing it one chunk at a time and now it needs to be refactored.
Each document type has an identifier (docID), and all of them share the same underlying result structure.
There is a huge master class that does all the job BUT inside this class there are several methods (almost one for each site) with its own logic. They all do almost the same with slight changes (i.e. formatting a string before setting it to a field in the result structure or doing some calculation and then setting the field in the result structure).
For example:
private Result processDocGeneric(Result result){
result.setField1("value1");
result.setField2("value2");
result.setField3("value3");
return result;
}
private Result processDoc1(Result result){
result.setField1("VALUE1");
return result;
}
private Result processDoc2(Result result){
result.setField2("V-A-L-U-E-2");
return result;
}
private void processDocs(){
Result result = new Result();
result = processDocGeneric(result);
if(docID == 1){
result = processDoc1(result);
}
else if(docID == 2){
result = processDoc2(result);
}
...
}
Ok, so I'm planning to refactor this and I'm considering some design patterns I know but I don't want the feel that I'm killing a roach with a bazooka.
Command pattern is maybe the first that comes to my mind, also Strategy pattern. My major concern with those is that I will have to create a class for every document type that has its own implementation of the processDoc method (There are around 15 at the moment). I mean, if that's the way to go, that would be it but if there's a simpler way of doing it that I don't know, it would be better (since the change is in a single method).
The other thing that I could do is moving all those method to a 'methods' class, and also move the if-else block to a single method with a docID parameter (process(int docID) and then call it from the main class. But that's just splitting the huge class. It would be "cleaner" but not optimal.
What would be the best approach to clean and split this huge class and make it scalable (since there would be new document types to be added in the future)?.
You can use factory or abstract factory design patterns maybe, In this patterns you can get your needed objects without having to specify the exact class of the object that will be created.
I propose a solution based on the Visitable / Visitor Pattern. this solution requires very little change to the Result class, while opening the door to new visiting objects, making it an easily extensible framework. I'm making heavy use of Java8's default interface method.
The Visitor / Visitable Interfaces:
public interface DocVisitor<T extends VisitableDoc> {
default void visit(T document){
switch(document.getDocId()){
case 1:
processDoc1(document);
break;
case 2:
processDoc2(document);
break;
// ... other cases...
default:
processDocGeneric(document);
break;
}
}
void processDocGeneric(VisitableDoc document);
void processDoc1(VisitableDoc document);
void processDoc2(VisitableDoc document);
}
public interface VisitableDoc {
int getDocId();
default void visit(DocVisitor visitor){
visitor.visit(this);
}
}
Slight modification of the Result class:
public class Result implements VisitableDoc { // New interface declared
int getDocId(){
return docId; // This might already exist
}
// Rest is unchanged, the default implementation will suffice
}
A Visitor Implementation:
public class DocProcessor implements DocVisitor<Result> {
#Override
private Result processDocGeneric(Result result){
result.setField1("value1");
result.setField2("value2");
result.setField3("value3");
return result;
}
#Override
private Result processDoc1(Result result){
result.setField1("VALUE1");
return result;
}
#Override
private Result processDoc2(Result result){
result.setField2("V-A-L-U-E-2");
return result;
}
}
Usage:
public static final main(String[] args){
List<Result> results = // Obtain results somehow
DocProcessor processor = new DocProcessor();
for(Result result: results){
processor.visit(result);
}
}
[How to] split this huge class and make it scalable (since there would be new document types to be added in the future
What I've done is merely to split Document data on Result class / Document Processing on DocProcessor class. If you have other processing that differ from type to type, and which can be extracted to an external class (no need for private field handling, private methods calling etc.), this framework os completely applicable.
If not, you should REALLY consider refactoring it to use polymophism! Make each Document type its own object. Use a strong abstract class to link them all, and if you have many methods that are shared accross several but not all types, then make sub-types accordingly - or use default methods! Java8 FTW
For this situation is applicable builder pattern.
/**
*
* Hero, the class with many parameters.
*
*/
public final class Hero {
private final Profession profession;
private final String name;
private final HairType hairType;
private final HairColor hairColor;
private final Armor armor;
private final Weapon weapon;
private Hero(Builder builder) {
this.profession = builder.profession;
this.name = builder.name;
this.hairColor = builder.hairColor;
this.hairType = builder.hairType;
this.weapon = builder.weapon;
this.armor = builder.armor;
}
public Profession getProfession() {
return profession;
}
public String getName() {
return name;
}
public HairType getHairType() {
return hairType;
}
public HairColor getHairColor() {
return hairColor;
}
public Armor getArmor() {
return armor;
}
public Weapon getWeapon() {
return weapon;
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("This is a ")
.append(profession)
.append(" named ")
.append(name);
if (hairColor != null || hairType != null) {
sb.append(" with ");
if (hairColor != null) {
sb.append(hairColor).append(' ');
}
if (hairType != null) {
sb.append(hairType).append(' ');
}
sb.append(hairType != HairType.BALD ? "hair" : "head");
}
if (armor != null) {
sb.append(" wearing ").append(armor);
}
if (weapon != null) {
sb.append(" and wielding a ").append(weapon);
}
sb.append('.');
return sb.toString();
}
/**
*
* The builder class.
*
*/
public static class Builder {
private final Profession profession;
private final String name;
private HairType hairType;
private HairColor hairColor;
private Armor armor;
private Weapon weapon;
/**
* Constructor
*/
public Builder(Profession profession, String name) {
if (profession == null || name == null) {
throw new IllegalArgumentException("profession and name can not be null");
}
this.profession = profession;
this.name = name;
}
public Builder withHairType(HairType hairType) {
this.hairType = hairType;
return this;
}
public Builder withHairColor(HairColor hairColor) {
this.hairColor = hairColor;
return this;
}
public Builder withArmor(Armor armor) {
this.armor = armor;
return this;
}
public Builder withWeapon(Weapon weapon) {
this.weapon = weapon;
return this;
}
public Hero build() {
return new Hero(this);
}
}
}

Using the Check class, add the code to have the Checks sorted by checkNumber

Using the Check class, add the code to have the Checks sorted by checkNumber.
import java.util.Date;
public class Check implements Comparable {
private int checkNumber;
private String payTo;
private Date date;
private float amount;
public int compareTo(Object arg0) {
//Insert code here
}
public int getCheckNumber() {
return checkNumber;
}
public void setCheckNumber(int checkNumber) {
this.checkNumber = checkNumber;
}
public String getPayTo() {
return payTo;
}
public void setPayTo (String payTo) {
this.payTo = payTo;
}
public Date getDate() {
return date;
}
public void setDate (Date date) {
this.date = date;
}
public float getAmount() {
return amount;
}
public void setAmount (float amount) {
this.amount = amount;
}
}
My solution is below, but it does not seem to work.
Can anyone help me with the solution?
public int compareTo(Object arg0) {
if(this.checkNumber == arg0.checkNumber)
return 0;
else
return this.checkNumber > arg0.checkNumber ? 1 : -1;
}
You didn't specify what you mean by "doesn't work", but reading your code, I'm assuming you get a compilation error.
The reason for this is because the code you were given has not specified a type for the comparable, so it doesn't know what type you even want to compare it to. It will use Object by default, which does not (by design) know a thing about Check's fields and methods.
The following modification is the best solution:
public class Check implements Comparable<Check> {
public int compareTo(Check arg0) {/* ...*/ }
}
This will force you to compare this to other Check's only and make arg0 a Check object, rendering its fields and methods available to you.
Should the parameters of the problem you were given not allow you to modify the provided code, then the (very very distant) second best solution is:
public int compareTo(Object arg0) {
Check other = null;
if(arg0 instanceof Check)
other = (Check)arg0;
// Other checks.
}
This adaptation would technically work for your problem given the stipulation that you are not allowed to modify the provided code, but is otherwise not at all recommended, as the contract for Comparable wants the type of object you wish to compare against to be specified, and not specifying it can introduce problems.
In fact, I'd say you are fully allowed to tell the person who gave you this problem that they are a terrible person for giving you a problem with this mistake in it, because not specifying a Comparable type is a really bad practice. Especially if they're teaching you how to program.

Array Of Methods That Return A String

I'm creating a kind of data testing program, and one specific part is giving me a huge amount of trouble. In my main method class there is one section where I need to send over a String of data as a parameter in a method to my methods class (let's call it ValidatorClass) and the idea being that the method will then return any validation errors or if there are none simply an empty String.
This would be fine except that I use "for loops" when going through my data to validate as doing it without is just too clunky. I tried to research about arrays of methods and found plenty of useful things that work with void methods but found nothing on any methods that return variables.
In a nutshell I'm asking: Is it possible to create an array of methods (or implement an array of objects to simulate an array of methods) that return a variable?
Here is some example code, but in the actual program the method's return would actually be used further on:
public class Validation{
public static void main(String args){
ValidatorClass valTest = new ValidatorClass();
String[] dataList = {"Andrew", "Jameson", "Male"}
for(int i = 0; i < dataList.length; i++){
String errors = valTest.testInput(dataList[i], i).validationList[i];
System.out.println(errors);
}
}
}
And in ValidatorClass:
public class ValidatorClass{
public String testInput(String data, int index){
//Tests the data by calling method "index" which corresponds to data type.
//ie. validateName would be index : 1, validateSurname index : 2 etc
String errors = validationMethodList[index](data); //Somehow add data as a parameter to it
return errors;
}
public String validateName(String name){
String errors = "";
if(name.length < 1){
errors += "Name Not Entered";
}
return errors;
}
public String validateSurname(String surname){
String errors = "";
if(surname.length < 1){
errors += "Surame Not Entered";
}
return errors;
}
public String validateGender(String gender){
String errors = "";
if(!gender.equalsIgnoreCase("male") || !gender.equalsIngoreCase("female")){
errors += "Invalid Gender";
}
return errors;
}
}
I imagine that you have something like...
static String validate1(Validatible v) { /* do something */ }
static String validate2(Validatible v) { /* do something else */ }
static String validate3(Validatible v) { /* do something still else */ }
And that you want to execute, in some method...
Validatible v = getValidatible();
System.out.println(validate1(v));
System.out.println(validate2(v));
System.out.println(validate3(v));
Then perhaps you could write an interface:
public interface Validator {
String validate(Validatible v);
}
...and keep them in an array or a list...
private static final List<Validator> validators = Arrays.asList(
new Validator() {
#Override
public String validate() {
/* do something */
}
},
new Validator() {
#Override
public String validate() {
/* do something else */
}
},
new Validator() {
#Override
public String validate() {
/* do something still else */
}
}
);
// Can be written more compactly if in Java 8.
Thereafter, you can call the methods in a for-loop:
Validatible v = getValidatible();
for(Validator validator : validators) {
System.out.println(validator.validate(v));
}
Possible improvements would include using a StringBuilder to build a single String (or using the Stream API and using Collectors.joining) if this fits your purpose better.

How to create a variable that can be set only once but isn't final in Java

I want a class that I can create instances of with one variable unset (the id), then initialise this variable later, and have it immutable after initialisation. Effectively, I'd like a final variable that I can initialise outside of the constructor.
Currently, I'm improvising this with a setter that throws an Exception as follows:
public class Example {
private long id = 0;
// Constructors and other variables and methods deleted for clarity
public long getId() {
return id;
}
public void setId(long id) throws Exception {
if ( this.id == 0 ) {
this.id = id;
} else {
throw new Exception("Can't change id once set");
}
}
}
Is this a good way of going about what I'm trying to do? I feel like I should be able to set something as immutable after it's initialised, or that there is a pattern I can use to make this more elegant.
Let me suggest you a little bit more elegant decision.
First variant (without throwing an exception):
public class Example {
private Long id;
// Constructors and other variables and methods deleted for clarity
public long getId() {
return id;
}
public void setId(long id) {
this.id = this.id == null ? id : this.id;
}
}
Second variant (with throwing an exception):
public void setId(long id) {
this.id = this.id == null ? id : throw_();
}
public int throw_() {
throw new RuntimeException("id is already set");
}
The "set only once" requirement feels a bit arbitrary. I'm fairly certain what you're looking for is a class that transitions permanently from uninitialized to initialized state. After all, it may be convenient to set an object's id more than once (via code reuse or whatever), as long as the id is not allowed to change after the object is "built".
One fairly reasonable pattern is to keep track of this "built" state in a separate field:
public final class Example {
private long id;
private boolean isBuilt;
public long getId() {
return id;
}
public void setId(long id) {
if (isBuilt) throw new IllegalArgumentException("already built");
this.id = id;
}
public void build() {
isBuilt = true;
}
}
Usage:
Example e = new Example();
// do lots of stuff
e.setId(12345L);
e.build();
// at this point, e is immutable
With this pattern, you construct the object, set its values (as many times as is convenient), and then call build() to "immutify" it.
There are several advantages to this pattern over your initial approach:
There are no magic values used to represent uninitialized fields. For example, 0 is just as valid an id as any other long value.
Setters have a consistent behavior. Before build() is called, they work. After build() is called, they throw, regardless of what values you pass. (Note the use of unchecked exceptions for convenience).
The class is marked final, otherwise a developer could extend your class and override the setters.
But this approach has a fairly big drawback: developers using this class can't know, at compile time, if a particular object has been initialized or not. Sure, you could add an isBuilt() method so developers can check, at runtime, if the object is initialized, but it would be so much more convenient to know this information at compile time. For that, you could use the builder pattern:
public final class Example {
private final long id;
public Example(long id) {
this.id = id;
}
public long getId() {
return id;
}
public static class Builder {
private long id;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Example build() {
return new Example(id);
}
}
}
Usage:
Example.Builder builder = new Example.Builder();
builder.setId(12345L);
Example e = builder.build();
This is much better for several reasons:
We're using final fields, so both the compiler and developers know these values cannot be changed.
The distinction between initialized and uninitialized forms of the object is described via Java's type system. There is simply no setter to call on the object once it has been built.
Instances of the built class are guaranteed thread safe.
Yes, it's a bit more complicated to maintain, but IMHO the benefits outweigh the cost.
I recently had this problem when writing some code to construct an immutable cyclic graph where edges reference their nodes. I also noticed that none of the existing answers to this question are thread-safe (which actually allows the field to be set more than once), so I thought that I would contribute my answer. Basically, I just created a wrapper class called FinalReference which wraps an AtomicReference and leverages AtomicReference's compareAndSet() method. By calling compareAndSet(null, newValue), you can ensure that a new value is set at most once by multiple concurrently modifying threads. The call is atomic and will only succeed if the existing value is null. See the example source below for FinalReference and the Github link for sample test code to demonstrate correctness.
public final class FinalReference<T> {
private final AtomicReference<T> reference = new AtomicReference<T>();
public FinalReference() {
}
public void set(T value) {
this.reference.compareAndSet(null, value);
}
public T get() {
return this.reference.get();
}
}
Google's Guava library (which I recommend very highly) comes with a class that solves this problem very well: SettableFuture. This provides the set-once semantics that you ask about, but also a lot more:
The ability to communicate an exception instead (the setException method);
The ability to cancel the event explicitly;
The ability to register listeners that will be notified when the value is set, an exception is notified or the future is canceled (the ListenableFuture interface).
The Future family of types in general used for synchronization between threads in multithreaded programs, so SettableFuture plays very nicely with these.
Java 8 also has its own version of this: CompletableFuture.
You can simply add a boolean flag, and in your setId(), set/check the boolean. If I understood the question right, we don't need any complex structure/pattern here. How about this:
public class Example {
private long id = 0;
private boolean touched = false;
// Constructors and other variables and methods deleted for clarity
public long getId() {
return id;
}
public void setId(long id) throws Exception {
if ( !touchted ) {
this.id = id;
touched = true;
} else {
throw new Exception("Can't change id once set");
}
}
}
in this way, if you setId(0l); it thinks that the ID is set too. You can change if it is not right for your business logic requirement.
not edited it in an IDE, sorry for the typo/format problem, if there was...
Here's the solution I came up with based on mixing some of the answers and comments above, particularly one from #KatjaChristiansen on using assert.
public class Example {
private long id = 0L;
private boolean idSet = false;
public long getId() {
return id;
}
public void setId(long id) {
// setId should not be changed after being set for the first time.
assert ( !idSet ) : "Can't change id from " + this.id + " to " + id;
this.id = id;
idSet = true;
}
public boolean isIdSet() {
return idSet;
}
}
At the end of the day, I suspect that my need for this is an indication of poor design decisions elsewhere, and I should rather find a way of creating the object only when I know the Id, and setting the id to final. This way, more errors can be detected at compile time.
I have this class, similar to JDK's AtomicReference, and I use it mostly for legacy code:
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import javax.annotation.Nonnull;
import javax.annotation.concurrent.NotThreadSafe;
#NotThreadSafe
public class PermanentReference<T> {
private T reference;
public PermanentReference() {
}
public void set(final #Nonnull T reference) {
checkState(this.reference == null,
"reference cannot be set more than once");
this.reference = checkNotNull(reference);
}
public #Nonnull T get() {
checkState(reference != null, "reference must be set before get");
return reference;
}
}
I has single responsibilty and check both get and set calls, so it fails early when client code misuse it.
Here are two ways; the first is basically the same as some others mentioned in other answers, but it is here to constrast with the seconds. So the first way, Once is to have a value that can be set only once by enforcing that in the setter. My implementation requires non-null values, but if you want to be able to set to null, then you would need to implement an 'isSet' boolean flag as suggested in other answers.
The second way, Lazy, is to provide a function that lazily supplies the value once the first time the getter is called.
import javax.annotation.Nonnull;
public final class Once<T>
{
private T value;
public set(final #Nonnull T value)
{
if(null != this.value) throw new IllegalStateException("Illegal attempt to set a Once value after it's value has already been set.");
if(null == value) throw new IllegalArgumentException("Illegal attempt to pass null value to Once setter.");
this.value = value;
}
public #Nonnull T get()
{
if(null == this.value) throw new IllegalStateException("Illegal attempt to access unitialized Once value.");
return this.value;
}
}
public final class Lazy<T>
{
private Supplier<T> supplier;
private T value;
/**
* Construct a value that will be lazily intialized the
* first time the getter is called.
*
* #param the function that supplies the value or null if the value
* will always be null. If it is not null, it will be called
* at most one time.
*/
public Lazy(final Supplier<T> supplier)
{
this.supplier = supplier;
}
/**
* Get the value. The first time this is called, if the
* supplier is not null, it will be called to supply the
* value.
*
* #returns the value (which may be null)
*/
public T get()
{
if(null != this.supplier)
{
this.value = this.supplier.get();
this.supplier = null; // clear the supplier so it is not called again
// and can be garbage collected.
}
return this.value;
}
}
So you might use these as follows;
//
// using Java 8 syntax, but this is not a hard requirement
//
final Once<Integer> i = Once<>();
i.set(100);
i.get(); // returns 100
// i.set(200) would throw an IllegalStateException
final Lazy<Integer> j = Lazy<>(() -> i);
j.get(); // returns 100
try have an int checker like
private long id = 0;
static int checker = 0;
public void methodThatWillSetValueOfId(stuff){
checker = checker + 1
if (checker==1){
id = 123456;
}
}
//u can try this:
class Star
{
private int i;
private int j;
static boolean a=true;
Star(){i=0;j=0;}
public void setI(int i,int j) {
this.i =i;
this.j =j;
something();
a=false;
}
public void printVal()
{
System.out.println(i+" "+j);
}
public static void something(){
if(!a)throw new ArithmeticException("can't assign value");
}
}
public class aClass
{
public static void main(String[] args) {
System.out.println("");
Star ob = new Star();
ob.setI(5,6);
ob.printVal();
ob.setI(6,7);
ob.printVal();
}
}
Marking a field private and not exposing a setter should be sufficient:
public class Example{
private long id=0;
public Example(long id)
{
this.id=id;
}
public long getId()
{
return this.id;
}
if this is insufficient and you want someone to be able to modify it X times you can do this:
public class Example
{
...
private final int MAX_CHANGES = 1;
private int changes = 0;
public void setId(long id) throws Exception {
validateExample();
changes++;
if ( this.id == 0 ) {
this.id = id;
} else {
throw new Exception("Can't change id once set");
}
}
private validateExample
{
if(MAX_CHANGES==change)
{
throw new IllegalStateException("Can no longer update this id");
}
}
}
This approach is akin to design by contract, wherein you validate the state of the object after a mutator (something that changes the state of the object) is invoked.
I think the singleton pattern might be something you should look into. Google around a bit to check if this pattern meets your design goals.
Below is some sudo code on how to make a singleton in Java using enum. I think this is based off Joshua Bloch's design outlined in Effective Java, either way it's a book worth picking up if you don't have it yet.
public enum JavaObject {
INSTANCE;
public void doSomething(){
System.out.println("Hello World!");
}
}
Usage:
JavaObject.INSTANCE.doSomething();

clever way to avoid try catch at each line

I am currently working with XML files, and am searching to have a better way to avoid try/catch blocks in a nice way.
Here is the thing. Let's say I have an XML file.
<A>
<BB>37</BB>
<CC>
<DDD>1</DDD>
</CC>
</A>
In fact, I turn this into an object, which means that I can do
myXml.getA() and so on.
In my code, I search a lot for given elements in this object, which means that I have a lot of lines like
int ddd = myXml.getA().getCC().getDDD();
The thing is that some elements may not be there, and for example another XML element can be like that only :
<A'>
<BB'>37</BB'>
</A'>
So if I try to get ddd, getCC() raises a NullPointerException.
In the end, I end up coding it like that :
int ddd;
try{
ddd = myXml.getA().getCC().getDDD();
}
catch (NullPointerException e){
ddd = 0;
}
This works but the code becomes really ugly.
I am searching for a solution to have something like
int ddd = setInt(myXml.getA().getCC().getDDD(), 0);
0 being the default in case the method raises an exception.
Is there a nice way to do that ?
Up to now, I couldn't find a solution that do not raise errors.
Thx for your help !
EDIT: Just not to get XML related answers.
I showed the xml part for everybody to understand the problem.
In my code, I don't have access to the XML, but only the object that represents it.
To make it short, what I'd really love is some kind of isNull method to test my getters.
This is sort of an annoyance of working with jaxb. in my company, we do enough work with jaxb that it was worth writing an xjc plugin which generated "safe" versions of every getter that were guaranteed to return non-null values for any non-trivial value (immutable instances in the case that a sub-object did not really exist).
Here's an example of what our generated model entities look like:
public class ExampleUser implements Serializable {
private final static long serialVersionUID = 20090127L;
#XmlAttribute
protected String name;
#XmlAttribute
protected String email;
public final static ExampleUser EMPTY_INSTANCE = new ExampleUser() {
private static final long serialVersionUID = 0L;
#Override
public void setName(java.lang.String value) { throw new UnsupportedOperationException(); }
#Override
public void setEmail(java.lang.String value) { throw new UnsupportedOperationException(); }
};
public String getName() {
return name;
}
public void setName(String value) {
this.name = value;
}
public String getEmail() {
return email;
}
public void setEmail(String value) {
this.email = value;
}
}
public class ExampleAccount implements Serializable {
private final static long serialVersionUID = 20090127L;
protected ExampleUser user;
#XmlElement(name = "alias")
protected List<String> aliases;
#XmlAttribute
protected String id;
#XmlAttribute
protected String name;
public final static ExampleAccount EMPTY_INSTANCE = new ExampleAccount() {
private static final long serialVersionUID = 0L;
#Override
public void setUser(com.boomi.platform.api.ExampleUser value) { throw new UnsupportedOperationException(); }
#Override
public List<String> getAliases() { return java.util.Collections.emptyList(); }
#Override
public void setId(java.lang.String value) { throw new UnsupportedOperationException(); }
#Override
public void setName(java.lang.String value) { throw new UnsupportedOperationException(); }
};
public ExampleUser getUser() {
return user;
}
public void setUser(ExampleUser value) {
this.user = value;
}
public List<String> getAliases() {
if (aliases == null) {
aliases = new ArrayList<String>();
}
return this.aliases;
}
public String getId() {
return id;
}
public void setId(String value) {
this.id = value;
}
public String getName() {
return name;
}
public void setName(String value) {
this.name = value;
}
public ExampleUser safeGetUser() {
return (getUser() != null) ? getUser() : ExampleUser.EMPTY_INSTANCE;
}
}
So you could write this code without fear of NPE:
userEmail = account.safeGetUser().getEmail();
You can look at the Null objec pattern.
For example :
public class A {
private C c;
public C getC() {
if (c == null) {
c = new C(0); // the "null object"
}
return c;
}
}
public class C {
private int d;
public C(int d) {
this.d = d;
}
public int getD() {
return d;
}
}
But personnaly, i have a bad feeling with this code :
int ddd = myXml.getA().getCC().getDDD();
It is a strong violation of the law of Demeter. The class invoker have a too large knowledge of A, C and D. This code will be clearly difficult to adapt and maintain.
The two general approaches to this sort of problem are the null object pattern that other answers have already covered, and type safe nulls such as Scala's Option.
http://www.scala-lang.org/api/current/scala/Option.html
There are a few Java versions of Option knocking around.
http://functionaljava.googlecode.com/svn/artifacts/2.20/javadoc/fj/data/Option.html
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Optional.html
Type safe nulls can be particular useful when combined with the flatmap.
Use Apache common-beanutils to create your set method. It will use reflection and then you have only a single place to catch the errors.
It would look something like this (haven't coded it so excuse syntax errors).
int getInt(Object root, String beanPattern, int defaultValue)
{
try
{
return PropertyUtils.getNestedProperty(root, beanPattern);
}
catch (Exception e)
{
return 0;
}
}
This would be called like so.
int ddd = getInt(myXml, "A.CC.DDD", 0);
Can't you just write a function which is general enough to be called for each value, and is returning the value or 0.
Something like
myGetSomething(FOO){
try {getFOO} catch ...
}
Then your Code itself looks nice, but the function has basically a try-catch for each call.
Use Xpath query instead of get methods. It will give you an empty list if it cannot find the element path.
List ddds = myXml.query("/AA/BB/CC/DDD");
if (!ddds.empty()) {}
The correct syntax depends on the XML library you use.
Write part of the code in Groovy or Xtend; both support the ?. syntax which returns null of the left hand side of the expression evaluates to null. They also get rid of the useless get so you can write:
myXml.a?.cc?.ddd
The syntax of Xtend is worse when compared to Groovy but it compiles to plain Java, so you just need to add a single JAR with some helper classes to your code to use the result.

Categories