i'm stuck with Thrift about data types.
Now when i map and Integer value to a thrift generated bean, i'm using i32 type in the idl definition.
class MyBean {
Integer i = null;
}
struct TMyBean {
1: i32 i;
}
The problem is that in TMyBean generated bean, the i var is an int primitive type, than it's putting 0 as the default value, and for me 0 it's a valid value.
I've tried to put the optional keyword in the idl file, but things are not changing, it's always int.
How i've to handle this situation? i need i to accept a null value in TMyBean i var.
Thanks, Phaedra..
The optional keyword was the right choice.
To test, whether or not a particular optional field is set or not, use the isset flags:
struct MyBean {
1: i32 IntValue
}
gives
public class MyBean implements org.apache.thrift.TBase<MyBean, MyBean._Fields>, java.io.Serializable, Cloneable, Comparable<MyBean> {
// ... lots of other code omitted ...
// isset id assignments
private static final int __INTVALUE_ISSET_ID = 0;
private byte __isset_bitfield = 0;
// ... lots of other code omitted ...
/** Returns true if field IntValue is set (has been assigned a value) and false otherwise */
public boolean isSetIntValue() {
return EncodingUtils.testBit(__isset_bitfield, __INTVALUE_ISSET_ID);
}
public void setIntValueIsSet(boolean value) {
__isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __INTVALUE_ISSET_ID, value);
}
// ... even more code omitted ...
}
Each generated java class (from a thrift struct) has methods to check if the primitives are set. It's more cumbersome than autoboxing but works.
Example: for a thrift struct TMyBean that has a property myValue, the following generated Java method would help to check if it's null:
isSetMyValue()
If you want to nullify the primitive, use:
setMyValueIsSet(false).
* I don't understand why Thrift decided not to use optional primitives as objects in Java and let autoboxing do it's magic. Perhaps because of large collections? Anyhow, sounds like another priority issue of preferring performance over simplicity.
Integer in java is a class, not a primitive. Thrift will only allow you to use defined primitives i16, i32, i64, double for numbers. i32 i is equivalent to int i; in Java; an int always defaults to 0 in Java if it is not set. If you want to use a class, then you have to have a Thrift definition for that class that you can reference.
Related
I have an Java class with a number of properties, some of which are optional.
In the example below the properties linkerNumber, linkerStatus, and linkerPressure are optional and represent a physical object that may or may not be attached to the device.
Right now I have mixed primitive and non-primitive types since linkerPressure is optional but flow, inputPressure, and outputPressure are required.
Should I:
Change all properties to be non-primitive for the sake of uniformity?
Mix primitive and non-primitive type to match what is/isn't required?
Represent linker values as their own object with a special null class (Null Object Pattern)?
My aversion to using the Null Object Pattern is that a separate linker object would not provide any additional functionality to me.
public class State {
private long serial;
private long received;
private String deviceId;
private String linkerNumber;
private String linkerStatus;
private Integer linkerPressure;
private int flow;
private int inputPressure;
private int outputPressure;
What is the best way to represent this data?
I would first think of the Builder pattern (if that is not already in place here), then I would wrap each optional parameter into an Optional from java.util (or guava if you are under java-8).
Thing is, even if you make them all Objects, the caller of getFlow for example (that will return an Integer) would probably not think of checking for null first and then acting on it, it will assume a non-null value. How many times do you check the return types of Objects againt null?
But getting an Optional<Integer> (or OptionalInt) forces the caller to think and act accordingly. Just notice that Optional<T> is used mainly for return types, denoting a potentially missing value.
To stay in accordance to that you could have something like:
class State {
private Integer flow; // nullable
public Optional<Integer> getFlow(){
return Optional.ofNullable(flow);
}
}
I have a custom object that has a single value of type int that I wanting to do processing on to keep this value in a set range. My question is this: Given the following class, can I set it's value with myObject = 0;
public class foo{
private int bar;
public foo(){
}
}
Instead of creating a method public void setBar()
If you mean:
foo x = new foo();
x = 10; // This is meant to set x.bar
then no, you can't do that in Java. Good thing too, if you ask me... it would be horrible in terms of readability.
You also can't change it to allow:
foo x = 10;
as equivalent to:
foo x = new foo();
x.bar = 10; // Or x.setBar(10);
No you can't do that. Java does not support operator overloading. Although + operator is overloaded for performing String concatenation, but that's the only exception. Another example that uses the = operator the way you would want is in case of wrapper classes, where you can directly assign a primitive type values to it's corresponding wrapper type, which causes the primitive value to be auto-boxed to wrapper type.
Integer val = 10; // 10 is auto-boxed to Integer reference
But it's only limited for that purpose. You can't do that for your own user-defined type.
Creating a method is your only option.
Foo myObject = new Foo();
Here, myObject holds the reference. You can't assign primitive value such as 0 to object references.
Instead, you should do myObject.setBar(10);
No, it goes against encapsulation logic, and Java Itself.
Abother possibility, you could make this field public. It would just need to do the validations you need in the business method (no during the set).
In Java, the convention is to provide setters and getters to change an object's inner attributes. For your case:
foo instance = new foo();
instance.setBar(10); //Sets bar to 10
instance.getBar(); //returns bar's current value (right now 10)
The setter receives the new value and sets it:
public void setBar(int newBar) {
bar = newBar;
}
And the getter gives access to the field's current value:
public int getBar() {
return bar;
}
You cannot, however, overload the = operator to do as setBar does, at least in Java. If you're thinking about, for example the Integer or Float wrapper classes, there's another force at work there, related to Java's implementation itself and that later derives in the concepts of boxing and unboxing.
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.
In C# I can a variable to allow nulls with the question mark. I want to have a true/false/null result. I want to have it set to null by default. The boolean will be set to true/false by a test result, but sometimes the test is not run and a boolean is default to false in java, so 3rd option to test against would be nice.
c# example:
bool? bPassed = null;
Does java have anything similar to this?
No.
Instead, you can use the boxed Boolean class (which is an ordinary class rather a primitive type), or a three-valued enum.
you can use :
Boolean b = null;
that is, the java.lang.Boolean object in Java.
And then also set true or false by a simple assignment:
Boolean b = true;
or
Boolean b = false;
No, in java primitives cannot have null value, if you want this feature, you might want to use Boolean instead.
Sure you can go with Boolean, but to make it more obvious that your type can have "value" or "no value", it's very easy to make a wrapper class that does more or less what ? types do in C#:
public class Nullable<T> {
private T value;
public Nullable() { value = null; }
public Nullable(T init) { value = init; }
public void set(T v) { value = v; }
public boolean hasValue() { return value != null; }
public T value() { return value; }
public T valueOrDefault(T defaultValue) { return value == null ? defaultValue : value; }
}
Then you can use it like this:
private Nullable<Integer> myInt = new Nullable<>();
...
myInt.set(5);
...
if (myInt.hasValue())
....
int foo = myInt.valueOrDefault(10);
Note that something like this is standard since Java8: the Optional class.
https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html
Yes you can.
To do this sort of thing, java has a wrapper class for every primitive type. If you make your variable an instance of the wrapper class, it can be assigned null just like any normal variable.
Instead of:
boolean myval;
... you can use:
Boolean myval = null;
You can assign it like this:
myval = new Boolean(true);
... And get its primitive value out like this:
if (myval.booleanValue() == false) {
// ...
}
Every primitive type (int, boolean, float, ...) has a corresponding wrapper type (Integer, Boolean, Float, ...).
Java's autoboxing feature allows the compiler to sometimes automatically coerce the wrapper type into its primitive value and vice versa. But, you can always do it manually if the compiler can't figure it out.
In Java, primitive types can't be null. However, you could use Boolean and friends.
No but you may use Boolean class instead of primitive boolean type to put null
If you are using object, it allows null
If you are using Primitive Data Types, it does not allow null
That the reason Java has Wrapper Class