Java instanceof not match Double - java

I have a Value Class and there is an Object value in it. I want to use the value as String, Integer or Double.
The asDouble method controls instanceof value object. If it is not Double or Integer returns 0.
Generally it works but sometimes although it is Double returns 0;. I couldn't the reason of it.
When I debug I can see:
Here is my Value class
public class Value{
public Object value;
public Value(Object value) {
this.value = value;
}
public Double asDouble() {
if (this.value instanceof Integer || this.value instanceof Double) {
return Double.parseDouble(String.valueOf(this.value));
} else {
return 0.0;
}
}
}
Could anybody explain where did I go wrong

Short Answer: Details matter.
Some info: The value class instance variable (also-known-as property or member variable) is a class named Value.
Since the class Value is neither the Integer nor the Double class,
the else branch will always execute.
The Value class also has a member variable named value,
which,
in your example,
has a type of Double.
In the screen shot you included,
the Value object has its value member variable set to a "thing" which also has the type Value.
I know this because the dialog shows "value= Value (id:82)".

first at all, i agree with Ole V.V.s, killjoys and david as comments.
your screenshot shows a Value-Object holding another Value-Object in its value-property
the comments and a possible solution are summed up in the following example-class
public class Value {
// visibility should be private
private final Object value;
// to be more type-save
// and to restrict
// this.values instance-type to Double, Integer and/or String
// provide three public constructors
public Value(final Double value) {
this.value = value;
}
public Value(final Integer value) {
this.value = value;
}
public Value(final String value) {
this.value = value;
}
public double asDoublePrimitive() {
if ((this.value instanceof Number)) {
return ((Number) this.value).doubleValue();
}
return 0.0;
}
public Double asDoubleObject() {
if ((this.value instanceof Number)) {
return Double.valueOf(((Number) this.value).doubleValue());
}
return Double.valueOf(0.0);
}
}
be aware that neither your nor my code consider the case that this.value is an instanceof String

instanceof check applies to full class definiton which includes the ClassLoader that loaded the class. Probably this.value was loaded by different ClassLoader and the check fails. You can confirm by trying:
ClassLoader cl1 = this.value.getClass().getClassLoader()
ClassLoader cl2 = Double.class.getClassLoader();
if (cl1.equals(cl2)) {
...
}
Although this can get even more trickier with parent-child relationships between ClassLoader objects this answer provides a good example when instanceof fails.
The other options is that your Double is not a java.lang.Double but that would be surprising.

Related

How can I set instance variables in classes that update constantly depending on the value of other instance variables?

I want to set an instance variable that relies on another.
I tried to define my new instance variable refering to another. For example:
public class numbers{
int value;
int triple=3*value;
.
.
.
}
I expected that whenever I updated the independent variable (in the example it would be value) through class methods, the variable triple would update along with the new value of value, but when I run the debugger the dependent variable stays at its default value.
The assignment in int triple = 3 * value; is only done once, to the value evaluated at that time. There is no inherent binding between those two variables after that point.
A common pattern for hiding the internals of the fields is to use getters and setters, where you could make your class behave like you want. Depending on how exactly you want that triple to behave, you could either set its value on the setter for value:
public class Numbers{
private int value;
private int triple;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
this.triple = 3 * value;
}
public int getTriple() {
return triple;
}
}
Or you could just get rid of the triple field completely, and just replace it with a method:
public class Numbers{
private int value;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public int getTriple() {
return 3 * value;
}
}
I left the setter for triple out for both cases, as its behavior would depend on what you want to do if the value is not divisible by three -- it seems like you want the value to be read-only anyway...
This line of code:
int triple=3*value;
... only gets executed once per object instantiation. At that point, value will be 0, therefore triple will also be 0 (= 3 * 0).
If you want something to appear to be constantly updated, use a getter method (it can be public or private depending on who needs to call it):
public class numbers{
int value;
private int getTripleValue() {
return 3 * value;
}
}
Then, each time you call getTripleValue(), the result will be calculated for value at that point in time, therefore always being 'up to date'.
Pro tip: Capitalise the first letter of your class names. It's a standard, and it makes it easier to tell classes apart from variable names.

Java How to chain with Math class

I am at the very basics of learning Java, I have tried searching for this answer but maybe I do not know what I am searching for.
I want to perform multiple operations on a number, so far the only way I know how to do that is the have intermediate variables with operations performed one at a time. This can't be the best way. The following is code in my main method that I would love to have work:
double sqrtAbsInput = promptForDouble("I can get the square root of the absolute value.");
double sqrtAbsOutput = sqrtAbsInput.Math.abs().sqrt();
System.out.println(sqrAbsOutput);
promptForDouble() method returns a double, it is the second line that concerns me most. The error I get is
"error: double cannot be dereferenced."
I assume what's going on is the variable needs to be the argument of the Math class methods, but I understand it could also have to do with the variable being a primitive type.
abs and sqrt aren't methods of double (which is a primitive, so it doesn't have any methods anyway - as noted in the error message you're getting), but static method of Math that take a double as an argument and return a double result:
double sqrtAbsOutput = Math.sqrt(Math.abs(sqrtAbsInput));
Math class does not implement "builder pattern" (for efficiency reasons), but you can create your own Math class implementation which allows chaining.
Here is an example:
public class MathBuilder {
private double value;
public MathBuilder(double value) {
this.value = value;
}
public MathBuilder abs() {
value = Math.abs(value);
return this;
}
public MathBuilder sqrt() {
value = Math.sqrt(value);
return this;
}
// other builder-math methods...
public double build() {
return value;
}
}
Usage:
double result = new MathBuilder(-10).abs().sqrt().build();
Or with Java 8:
public class MathBuilder {
private double value;
public MathBuilder(double value) {
this.value = value;
}
public MathBuilder apply(DoubleUnaryOperator o) {
value = o.applyAsDouble(value);
return this;
}
public double build() {
return value;
}
}
Usage:
double result = new MathBuilder(-10)
.apply(Math::abs)
.apply(Math::sqrt)
.build();
You will have to do this:
System.out.println(Math.sqrt(Math.abs(sqrtAbsInput)));

How to implement a basic pointer

I know here is no pointer in Java. But how do I change a value in the calling scope? For instance, I want to write a function that takes an integer num, set the integer to 0 if it's greater than 21, otherwise do nothing.
In the main, my code is as follow:
int a=34;
KillOver21(a);
System.out.print(a);
I expect an 0.
Java is pass by value, so a copy of the parameter a is sent to the method, so modification to a in the method will not affect the original argument a in main
The max you can do is return int from KillOver21(a) method
int z = KillOver21(a); // This will return 0
System.out.print(z);
But you can achieve something like that with custom objects, say you have a class
class AHolder {
public int a;
}
then you can expect AHolder instance to change
public static void main(String [] args) {
AHolder a = new AHolder();
a.a = 34;
killOver21(a);
System.out.println(a.a);
}
public static void killOver21(AHolder b) {
if(b.a > 21) {
b.a = 0;
}
}
Since in the latter (even if its Pass by Value) , the reference is copied and both reference point to same object. So changes made inside the killOver21 method actually changes the object.
It is simply not possible, Java supports pass by value. int a's value will be copied to the function.
You could use Object instead of primitive where the reference value will be copied to your function by which you can get the actual object and modify it.
Fundamentally impossible in Java, period. int are immutable, and passed by value. You would need to create a mutable int type:
class MutableInt {
private int value;
public MutableInt(int value) { this.value = value; }
public getValue() { return this.value; }
public setValue(int value) { this.value = value; }
}
Then:
void KillOver21(MutableInt m) {
if(m.getValue() > 21) { m.setValue(0); }
}
However, be aware the mutable types that represent concepts that are defined by their value rather than their identity are generally an extremely bad idea. But, this is the only way to achieve what you're trying to achieve. Again, I caution you with the strongest words: what you're doing is a bad idea. You should find another way.
Doc, it hurts when I do this.
Then don't do that!
The simpliest way (quick&dirty) is to put value within an array
int holder[] = new int[]{ a};
KillOver21(holder)
System.out.printf( "value=[%d]", holder[0] );
void KillOver21(int holder[] ) {
holder[0] = 0;
}

Dynamic casting in Java

Before I get chided for not doing my homework, I've been unable to find any clues on the multitude of questions on Java generics and dynamic casting.
The type Scalar is defined as follows:
public class Scalar <T extends Number> {
public final String name;
T value;
...
public T getValue() {
return value;
}
public void setValue(T val) {
this.value = val;
}
}
I would like to have a method that looks like this:
public void evilSetter(V val) {
this.value = (T) val;
}
Sure, this is generally discouraged. The reason I want such a method is because I have a collection of Scalars whose values I'd like to change later. However, once they go in the collection, their generic type parameters are no longer accessible. So even if I want make an assignment that's perfectly valid at runtime, there's no way of knowing that it'll be valid at compile time, with or without generics.
Map<String, Scalar<? extends Number>> scalars = ...;
Scalar<? extends Number> scalar = scalars.get("someId");
// None of this can work
scalar.value = ...
scalar.setValue(...)
So how do I implement a checked cast and set method?
public <V extends Number> void castAndSet(V val) {
// One possibility
if (this.value.getClass().isAssignableFrom(val.getClass()) {
// Some cast code here
}
// Another
if (this.value.getClass().isInstanceOf(val) {
// Some cast code here
}
// What should the cast line be?
// It can't be:
this.value = this.value.getClass().cast(val);
// Because this.value.getClass() is of type Class<?>, not Class<T>
}
So I'm left with using
this.value = (T) val;
and catching a ClassCastException?
You have:
this.value.getClass().isAssignableFrom(val.getClass())
This is probably going to be a problem unless you can be certain value will never be null.
You also have:
this.value = (T) val;
This will only cast to Number and not to T because under the hood T is just a Number due to type-erasure. Therefore if value is a Double and val is an Integer, no exception will be thrown.
If you actually want to perform a checked cast, you must have the correct Class<T> object. This means you should be passing Class<T> in the constructor of your object. (Unless you can be sure value is never null, in which case you can go with your first idea.) Once you have that object (stored in a field), you can perform the checked cast:
T value = valueClass.cast(val);

Is there a way for a Java enum to have "missing" integer values for its elements?

For example, I have two elements in an enum. I would like the first to be represented by the integer value 0 and the string A, but the second to be represented by the integer value of 2 and the string "B" (as opposed to 1). Is this possible?
Currently, my enum is declared as this:
public enum Constants {
ZERO("Zero");
TWO("Two");
}
If I were to get the integer values of ZERO and TWO, I would currently get 0 and 1, respectively. However, I would like to get 0 and 2.
I assume you are referring to a way to make the ordinal of the Enum return a user-defined value. If this is the case, no.
If you want to return a specific value, implement (e.g. getValue()) and pass it in the Enum constructor.
For example:
public enum Constants {
ZERO("Zero",0),
TWO("Two",2);
final private String label;
final private int value;
Constants(String label, int value) {
this.label = label;
this.value= value;
}
public int getValue() {
return value;
}
public String getLabel() {
return label;
}
}
Define an appropriately named integer field for your enum and initialize it to whatever value suits you best. The internal ordinal of enums is not meant to carry an meaning.
try something like this:
public enum MyEnum {
A(1), B(2), C(3);
int myOrdinal;
private MyEnum(int myOrdinal) {
this.myOrdinal = myOrdinal;
}
public int getMyOrdinal() {
return myOrdinal;
}
If you rely on the internal numbering of the enum, then ordering matters and even different jvm's could handle it differently, which would lead to unpredictable behaviour (unless it is specified in the "enum jsr-161", haven't read it...).
I saw an implementation that relied on the inner ordinal, it was used for the ordering in a web dropdown box. It produced funny bugs once someone had kindly "clean up" the enum values..
You want to pass an integer in the constructor, then use
String input = ...
int inputAsInt = Constants.valueOf(input.toUpperCase()).getValue();
Something like
public enum Constants{
ZERO(0),
TWO(1);
private final int value;
public Numbers(int value){
this.value = value;
}
public int getValue(){
return this.value;
}
}

Categories