I have a class like so:
public class Achievements(){
boolean score100_Earned_Offline;
boolean score1000_Earned_Offline;
final String score100 = "xxxxxxxxxx" //where xxxxxxxxxx would be replaced with the achievement's Google Play Games ID
final String score1000 = "xxxxxxxxxx" //where xxxxxxxxxx would be replaced with the achievement's Google Play Games ID
}
In my Game class, I check the state of the achievements every tick and act on them as necessary like so (assume all methods to be valid and defined - this is cut down to provide the code necessary to the question).......
public class Game(){
public void checkAchievements(Achievements achievements){
if (score>=100){
unlockAchievement(achievements.score100, achievements.score100_Earned_Offline);
}
if (score>1000){
unlockAchievement(achievements.score100, achievements.score1000_Earned_Offline);
}
}
public void unlockAchievement(String achievementToUnlock, boolean thisAchievementOfflineFlag){
//If user is signed in, then we are ready to go, so go ahead and unlock the relevant achievement....
if (checkSignedIn()){
Games.Achievements.unlock(getApiClient(), achievementToUnlock);
//Otherwise, I want to do is set the relevant flag to true so it can be checked when the user does eventually log in
else{
thisAchievementOfflineFlag=true;
}
}
}
Pass by value
In the 'unlockAchievement' method, the boolean 'thisAchievementOfflineFlag' does get set to true if the user is not logged in, however, it doesn't effect the actual boolean that was originally sent into the method (which as you can see is defined in my 'Achievements' class). I'm guessing this is because Java is Pass by Value and is therefore, creating a local copy of the variable which is valid inside the method only. I did try using Boolean too (wrapper class) but got the same results.
Other ways to achieve this?
I've currently got it set up so I can define each achievement as an enum so each one will have it's own copy of the boolean flag. However, I'm aware that it's not recommended to use enums in Android so if there is a better way that I am missing, I would rather avoid them.
Please note that I don't want to use if checks or switch statements as this is taking place in a game-loop.
Any suggestions appreciated
This is all because Java's implementation of Boolean (also, for example String) is immutable for safety reasons. You can see it here: http://www.explain-java.com/is-string-mutable-in-java-why-wrapper-classes-immutable-in-java/
You can solve your problem by introducing an object wrapper for that boolean:
public class BooleanWrapper {
private boolean value;
public void set(boolean value) {
this.value = value;
}
public boolean get() {
return value;
}
}
Now, this object reference will be passed by value but will still point to the same BooleanWrapper object on the heap. You can simply use getters and setters to change the inner boolean value.
Then your code would become:
public void unlockAchievement(String achievementToUnlock, BooleanWrapper thisAchievementOfflineFlag){
if (checkSignedIn()){
Games.Achievements.unlock(getApiClient(), achievementToUnlock);
else {
thisAchievementOfflineFlag.set(true);
}
}
Java is pass-by-value:
When you pass boolean then you for sure passed it by value, while it is a primitive type. When you pass Boolean, you would think it's an object and that you can change it's state, but actually you cannot because Boolean is implemented as an immutable object (as already said). You can confirm this just by reading the code of java.lang.Boolean.
But if you create your own wrapper class, and in a sense, you control whether you implement it in immutable or mutable way. BooleanWrapper I wrote lets you change the state of that object. And when you pass an object such as this one to the method, it's passed by value. That means that another reference is created, but it points to the same object on heap (see image below).
You could use an AtomicBoolean, which will have pass-by-reference semantics.
Related
In java an AtomicMarkableReference can be used to update atomically an object reference along with a mark bit.
The javadoc states:
Implementation note: This implementation maintains markable references by creating internal objects representing "boxed" [reference, boolean] pairs.
This is true according to what can be seen in the java 8 source code of the class:
package java.util.concurrent.atomic;
public class AtomicMarkableReference<V> {
private static class Pair<T> {
final T reference;
final boolean mark;
private Pair(T reference, boolean mark) {
this.reference = reference;
this.mark = mark;
}
static <T> Pair<T> of(T reference, boolean mark) {
return new Pair<T>(reference, mark);
}
}
private volatile Pair<V> pair;
public AtomicMarkableReference(V initialRef, boolean initialMark) {
pair = Pair.of(initialRef, initialMark);
}
// [...] class methods
}
Is there a reason behind the design of the get method of the class?
public V get(boolean[] markHolder) {
Pair<V> pair = this.pair;
markHolder[0] = pair.mark;
return pair.reference;
}
What is the point of using such boolean array (instead of returning the pair of values)? Is a concurrency-driven choice? Or perhaps legacy code?
This is because Java has no Pair<L, R> class and probably will not, even despite of the fact that standard library has at least three classes which have private static class Pair. Adding Pair class were discussed by OpenJDK developers more than once and proposal was always rejected. This mail is a very good explanation why pair shouldn't be presented as standard class (also, the whole mail thread is very useful):
The problem is that classes like Pair simply go that much further to indulge
the desire to never have to create any actual types of our own. When we're
forced to create our own types, we begin to model our data more
appropriately, which I believe leads us to create good abstractions at
broader levels of granularity as well.
As long as AtomicMarkableReference doesn't expose its Pair class and in Java you can't change value of passed reference (in the way that such change will be observable by caller), the only way to return both reference and bit flag is to return one of them from method and set second into passed as argument array. So it's not about concurrency, neither about legacy, it's about language design decision.
I had been thinking of using a generic factory pattern for this, however I just want to make sure that I am using it correctly.
First of all, this has to be Java-based, due to client needs.
My application can instantiate several objects, and each of those objects should be able to change type at run time. For instance, a variable can start out as a float, be converted to an int, then to a char, then back to a float. That would be a basic example, however custom data types can be added in for extra fun.
Is a generic factory pattern the correct one to use in this case? Or, is there something better? To me, the factory pattern seems to be better at instantiating and not updating (unless if I essentially destroyed and re-instantiated the variable).
More detail:
This is an evolutionary algorithm where I don't necessarily know the types when the program starts. It may find that an int is more desirable than a float, based on how evolution goes.
For instance, if I start with a floating point value of 4.34:
// start of program
object var = 4.34;
// evolution running......
...
// evolution determines that var would be better as a float
var.convertToInt();
// var is now an int with a value of 4
My initial thought had been to have a generic factory type object where I keep track of the current 'type' of the object and return the appropriate value. So in the beginning it would return a float, and after the conversion would return the int-converted value (mapped to an internal int).
Edit 2: Code clarification.
I guess my point is just not coming through. Here is an example of what I would expect to see, code-wise.
object var = new object(int, 4); // create int variable with value of 4
// where object is whatever base design pattern i am using here
...
var.toFloat(); // convert var to float, value is now 4.0
System.out.println(var.getValue()); // prints 4.0
...
var.toCustomClass(); // var is now a custom datatype
System.out.println(var.getValue()); // calls the print method of the class
I should also mention that the instance of var needs to persist throughout execution, as it is an object within my evolutionary algorithm and can't be destroyed and re-instantiated as something else.
If you explain why you want to do this it might help. Your best bet based on what you have said so far will be just to always use the type as Number and then store whatever version you need. For example number.toInt, number.toDouble etc.
For more complex types define a common interface that they all implement and store them using that interface, then write appropriate mapping methods or use a library such as Dozer to do the mapping for you.
You are going to need to create your own class to handle this. For example:
public class Value {
Object value;
Object getValue();
void toInteger() {
if (value instanceof Number) {
value = Integer.valueOf(((Number)value).intValue());
} else {
// Handle the conversion however you handle it
}
}
}
Maybe this can help.
By providing a generic method, the return type is casted to the type of the variable to hold the result. A ClassCastException will be launched if the types are not compatible
public class Wrapper {
private Object src;
public Wrapper(Object o) {
src = o;
}
public String getType(){
return src.getClass().getName();
}
public <E> E getValue() {
return (E)src;
}
public void toInteger(){
//dummy implementation
if(src instanceof Double){
src=new Integer(String.valueOf((int)Math.floor((Double)src)));
}
}
public static void main(String args[]){
Wrapper wrapper=new Wrapper(new Double(4.8));
System.out.println(wrapper.getType());
Double myDouble=wrapper.getValue();
System.out.println(myDouble);
wrapper.toInteger();
System.out.println(wrapper.getType());
Integer myInteger=wrapper.getValue();
// Double exceptionInProgress = wrapper.getValue();
System.out.println(myInteger);
}
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
This question may seem dumb at first, but after having worked with different person, I see everyone seems to have their own, different knowledge about it, so here's my question.
So now I'm wondering what is the best way to do it, and why ("why" is more important for me):
I'm wondering about two methods to write Java code:
Do you always pass Object or can you pass primitive data type ?
Do you call variables using this.name, name or getName() inside your class instance ?
public class MyClass {
private String someStr;
private int someNumber;
private Integer someOtherNumber; // int, Integer ? which one to choose ?
public MyClass(String someStr, int someNumber, int someOtherNumber) { // int someNumber ? Integer someNumber ? why ?
this.someStr = someStr; // Here, it's clearly this.{name} = {name} because of the variable name conflict
this.someNumber = someNumber;
this.someOtherNumber = someOtherNumber;
}
public int someMethod(boolean first) { // Boolean ? boolean ?
if (first) {
return someNumber;
} else {
return this.someOtherNumber; // this.{name} ? just {name} or even this.get{name}() or get{name}() ? (supposing getters exists)
}
}
}
I hope someone will provide me with a great explanation about which to use in order for me to write better code.
Do you always pass Object or can you pass primitive data type ?
You can't pass an Object, only a reference to an Object. You can pass primitive data.
Do you call variables using this.name, name or getName() inside your class instance ?
I don't make it more complicated than I need to, unless it's conflicts with a local variable or my getName() does something special, but that is a matter of style.
Do you always pass Object or can you pass primitive data type ?
You can pass primitives or references to objects depending on your need.
Do you call variables using this.name, name or getName() inside your
class instance ?
this is used to refer to the current object. If there are conflicting variable names and you want to distinguish between the object variable and local variable then use this.
Also you seems to be confused about primitives and Wrapper classes. Wrapper classes provides utilities methods and are of use especially working with collections.
If you need to work with the primitive data types then you should use them, e.g., int, double, char, float, etc. The only exception is String which in Java is a special class that represents a char array and also holds instance methods.
The case with Integer vs int, is when you need to use Integer methods (http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Integer.html). But if you only need a data type to hold your value then choose int.
Do you always pass Object or can you pass primitive data type ?
public int someMethod(boolean first) { // Boolean ? boolean ?
}
In the following example, you can pass boolean and Boolean with the same success. In Java this is called Autoboxing.
N.B. Be careful, because when passing an object it may be null!
Do you call variables using this.name, name or getName() inside your
class instance ?
Depends. If name is an class member variable, you can access it with name if there isn't any other variable in the current scope that has the same name. In this case you should use this.name to point exactly to the class member variable. getName() may be used, as well. It's just a matter of style.
I keep it simple. I'm using name, but if I have a local variable with the same name I must use this.name (my prefered solution) over getName().
getName() must be used if it do some logic like validation.
Do you always pass Object or can you pass primitive data type ?
It depends on your application and your needs. If you pass a reference to an object, you are able to use the methods of the related type which may be more secure and portable. Let say you are using the class Double. Double has many peer-reviewed and tested methods which may be helpful to you.If you prefer to use primitive type, double, you need to be careful in your manipulations like comparing, validating etc.
For performance issue, you may check a previous discussion below:
Why do people still use primitive types in Java?
Do you call variables using this.name, name or getName() inside your class instance ?
I prefer using this when I refer a class member because i think it will be helpful for others reading my code to understand that the variable is a class member.
Finally, whatever style you prefer, I think you should stick to it in your applications.
Do you call variables using this.name, name or getName() inside your class instance ?
It is mostly a matter of personal style and principle.
private int someOtherNumber; I almost always use int because it seems more natural to me --perhaps influenced by the C days. And, from performance and memory usage point of view using int is a better choice. As a rule of thumb, I don't use objects for primitives unless I have a good reason to.
return this.getSomeOtherNumber(); I prefer using getters/setters; since sometimes -not always- the getter method is not just a simple return statement, rather it encapsulates some logic. As a result, I don't directly access class attributes (like this.someAttr or someClass.somePublicAttr) unless it's a final attribute. Believe me, it's much safer.
Continuing 2: It may seem a bit strange but I, having a strong Lisp background, try to avoid using even getter/setter methods (class state) as much as possible and instead explicity pass the required parameters and use the methods' return values. Consider the following example:
public class C {
private int a;
private int b;
public int getA() { return a; }
public void setA(int a) { this.a = a; }
public int getB() { return a; }
public void setB(int b) { this.b = b; }
// Usual style
public void someMethod1(int x) {
mainLogic1(x);
}
private void mainLogic1(int x) {
b = a + x;
}
// My preferred style
public void someMethod2(int x) {
setB(mainLogic2(x, getA()));
}
private int mainLogic2(int x, int a) {
return x + a;
}
}
As you can see, someMethod1 and mainLogic1 both have side effects which are hard to detect when looking at the code. On the other hand mainLogic2 doesn't have a side effect at all and someMethod2 side effect is easier to spot by just looking. This may seem like overkill, but it has made my Java code more readable, more testable and easier to refactor as it consists of large number of small methods with no side effects.
Reedited...
public EventData getEventDetails(String evtId, String Status) {
//do some data selection here.
return evData1;
}
public EventData[] getAdminAuthEvtDetails(String evtId, String Status) {
String eId=evtId;
String status=Status;
EventData[] evData=new EventData[2];
EventData[0] evData=getEventDetails(eId,"V");
EventData[1] evData=getEventDetails(eId,"M");
return evData;
}
EventData is my java data class. In there I set getters and setters. I want to call getEventDetails method two time one status as verified and other as modified for requested ID and set both evData into one array. In here there give a error couldn't get data into EventData[0] and EventData[1].Is there any error of calling my getEventDetails method?
Finally I got correct code.
EventData[] evData=new EventData[2];
evData[0]=getEventDetails(eId,"V");
evData[1]=getEventDetails(eId,"M");
return evData;
in both methods you must return an object rather than Type
in 1st method:
public EventData getEventDetails(String evtId, String Status) {
return new EventData(evtId, status);//don't know how is you constructor of EventData, but its just a smart guess. the idea is to create an object
}
and in 2nd method return eData;
I believe you need to update your getEventDetails method as well. EventData is a class however you need to return an instance of the class generally created by calling the constructor new EventData().
Otherwise, ay89 is correct that getAdmin... should return eData.
Conceptually, it's correct. You just have some syntax issues that others have mentioned (like returning a variable instead of a class).
Otherwise, some other things to note:
You'll want to probably use a lowercase "s" for "Status" since conventionally, variables shouldn't start with upper cases.
You probably dont need to redeclare the evtId to eid. You can just use the evtId (and the incorrectly cased Status) variable directly.
Personally, I like to perhaps call the getEventDetails(...) method something more like createEventDetails(...) since it's more indicative of the function of that method. "Get" always implies fetching instead of creating to me.
Just my 2c
This is maybe so silly.
I have a boolean variable inside the main method. By calling another method of this class or another class I want my boolean value to be modified in the main method. I do this but the change happens only in the called method(locally), not the caller(main). I think this is because of the pass-by-value feature of java.
I even tried Boolean type, but the same problem there!
Actually I'll use this to manage the ordering of concurrent threads. The main processor will check for the boolean value of every thread to see if it is ok to continue and tick the clock. After ticking the clock the main will make the vars false and will wait until the vars are again true. the sub-threads will start their task if the boolean value of them each is false. After the task is done they will make the vars to true so the main processor is able to tick again.
So I want something without a return. I mean as the value is changed inside the method the main could see it.
boolean var = true;
var = methodWhichReturnsTheNewValueOfTheVariable();
and inside the called method:
return newBooleanValue;
or
SomeObjectWithBooleanVariableInside var = new SomeObjectWithBooleanVariableInside(true);
methodWhichModifiesTheObject(var);
and inside the called method:
var.setBooleanValue(newBooleanValue);
A Boolean is such an object: it contains a boolean value. But it's intentionally designed as immutable: its wrapped boolean value can't be changed. So you need to create your own, functional object.
The usual way to do this is the following:
public static void main(String[] args) {
boolean myVar = true;
...
...
myVar = myFunction();
}
public static boolean myFunction() {
// the method should do it's calculation and return the value:
return false;
}
Yes - you cannot modify passed-by-value parameter inside a method in Java (for example in C# you would write method(ref param)).
Why can't you return this value using the method:
public boolean method(params...) {...}
Or you can pass in param the reference to caller:
public void method(params..., CallerClass caller) {
//do something
caller.setValue(Boolean.FALSE);
}
Or you can make this variable accessible in caller and calling method scopes - static variable, etc.
Primitive types are passed by value, so you can't change variables coming as parameter in a method.
This makes also easier to understand how a program works, since this kind of behavior is made more evident in an invocation like this:
boolean prime = false;
prime = isPrime(number);
you can see that found variable is reassigned; while you can assume that number will remain unchanged. This helps in code readability.
There is a dirty trick that sometime can be used. Since arrays are objects, you can use an array to wrap a primitive type:
boolean[] prime = { false };
isPrime(number, result);
public void isPrime(int number, boolean[] result) {
result[0] = true;
}
The object reference is passed by value too, but here we change the content of the array, not the array reference.
This works. But, I don't recommend to design your code like this.
Sometimes, knowing this trick can be useful in unit tests though.
when you think that you changed the value of the primitive boolean it only changed the value in the scope of that method. same with Boolean as it is immutable. changing its value actually assigned a new value to it inside the scope of that method.
you should return the new value from that method and then assign it or you could also use a global boolean that is known to all and to change that one.
(and by the way, if you're dealing with concurrency check out AtomicBoolean)