I am trying to rewrite (for a educational reasons) Java code to PHP. It's in this repository. My problem is here on line 42. We can see there the following code:
if (this.getBoard().getTile(boxNextPlace) instanceof ContentOperations &&
((ContentOperations)this.getBoard().getTile(boxNextPlace)).getContent() == null)
{
...
As first step we check if this.getBoard().getTile(boxNextPlace) returns object implementing ContentOperations interface. If so, we go to step two, calling the this.getBoard().getTile(boxNextPlace) chain again, but this time we cast returned value to ContentOperations and then invoke the getContent method for further processing (in this case to compare it with null, .getContent()==null but this is irrelevant to my question).
As far as I understand casting in this case is some kind of protection from calling method not implemented by the object, but it is already proven by this.getBoard().getTile(boxNextPlace) instanceof ContentOperations condition, that object is of ContentOperations type.
So the question is: why is casting an object to its interface necessary if it is proven to be of the required type? Or maybe my understanding of this protective function of casting is wrong?
The person who wrote the Java code does an instanceof check on line 42, but they neglect to do one again on line 55. If getTile() really could return an object that isn't a ContentOperations, a ClassCastException would occur. I would assume that you don't need any extra logic in PHP to account for a different return type.
Related
I'm currently using Immutable library for generating JSON object from my web application.
Looking at this chapter, the first line says:
The use of nullable attributes is discouraged.
So my question is:
1) why? what's wrong with a null object?
2) what if I'm using a wrapper of thirdy object and I don't know if item is null or not, so using the classing builder code will fail:
MyImmutableWrapperObject
.builder().
.mobile(input.getMobile()) // don't know if null or not
.build();
Is there any optimal solution?
EDIT:
#JsonProperty("mobile")
public abstract Optional<String> mobile();
...
// composing builder
if (input.getMobile() != null)
builder.mobile(input.getMobile());
The produced json is:
"mobile": {
"present": false
},
How can I completely remove the empty fields?
I read this, however it uses gson.toJson which return a String object which is not my desiderable way.
POSTEDIT:
I just found that Optional doesn't show real value even if present, but it just display the true/false value, so I don't need it.
That's exactly the point IMO, you don't know if an object is null or not; so when later using it you might obviously get a NullPointerException. By using a library that prohibits that, you will not care if something is null or not null (because it will not be null), thus less code and less if-statements that pollute the code with potential null checks.
Also having a null reference might mean different things in different contexts. For example I've seen code that needs three states for a Boolean : true, false and no yet set(as null). I find that wrong, but still occasionally see it.
That's the reason why Optional was introduced in Guava and now is in the JDK. It forces the user to actively do something with an Optional. For example:
Optional<Integer> i...
if(i.isPresent()).... // you are forced to do this check
Well obviously you could do:
i.get()
but that method is documented that it might break.
the same is simply not true for an reference:
Integer i = null;
if(i == null) // this is not an operation that is mandatory
The bet article I've seen/read to date on this subject is Guava explanation
Why would someone do this?
private Number genericObjectToNumber (Object obj)
{
if (obj instanceof Byte)
{
return(new Byte((Byte) obj));
}
else if (obj instanceof Short)
{
return(new Short ((Short) obj));
}
.....
else if(obj instanceof BigInteger)
{
return(BigInteger.ZERO.add ((BigInteger) obj));
}
return(null); // if it isn't a number, we don't want it
}
Why not only return the cast? Why go through the constructor of a new object? Why not ask if obj instanceof
if (obj instanceof Number)
{
return((Number)obj);
}
I think there is no valid reason to do this. It could make sense if the objects were mutable and you’d want to create copies of these objects. But the primitive wrapper classes are immutable, so calling the constructors using the existing objects doesn’t make sense.
I think, the author was trying to make a generalized copy function.
The way it is works is like hes is trying to create a new object if this object is a number, returning a number in a new instance; e.g:
Byte(byte value)
Constructs a newly allocated Byte object that represents the specified byte value.
probably, if it is to make sense, he might have lots of data and does not know if is a number or not while operating. as such he wants to operate just with numbers, or wants to use a common unit after and avoid exceptions if not numbers. I am not saying this the way to go on those cases, but it might make sense (as an explanation not a recommendation, sounds like a c++ program wrote the code). BTW, as noticed on other answers, the objects are immutable, so if this is a real example, there is not good reason for that.
It makes no sense for several reasons:
Primitive types are immutable, there's no reason to go through the "new" constructor
It makes no sense to differentiate the different classes since the function returns a Number in the end
Even if differentiating and creating a new instance was necessary it would probably be better to write a generic method http://docs.oracle.com/javase/tutorial/java/generics/methods.html (unless the code was written in some old version of java that didn't support generics), then replicating so much code (although it would compile-check for numbers which may not be desired)
The only plausible reason I could think is if the list does not contain all types of numbers and the programmer wants to white-list the supported types of numbers, but even then, the method is ill-named
Because the original code is clearly meant to differentiate between different kinds of numbers. If you just returned "Number", then the obj would be casted to a Number (even if it wasn't actually a number) possibly resulting in a ClassCastException. By using the original code, the user is able to somewhat safely cast the obj to the proper type.
Guava's Optional pattern is great, as it helps remove the ambiguity with null. The transform method is very helpful for creating null-safe method chains when the first part of the chain may be absent, but isn't useful when other parts of the chain are absent.
This question is related to Guava Optional type, when transformation returns another Optional, which asks essentially the same question but for a different use case which I think may not be the intended use of Optional (handling errors).
Consider a method Optional<Book> findBook(String id). findBook(id).transform(Book.getName) works as expected. If there is no book found we get an Absent<String>, if there is a book found we get Present<String>.
In the common case where intermediate methods may return null/absent(), there does not seem to be an elegant way to chain the calls. For example, assume that Book has a method Optional<Publisher> getPublisher(), and we would like to get all the books published by the publisher of a book. The natural syntax would seem to be findBook(id).transform(Book.getPublisher).transform(Publisher.getPublishedBooks), however this will fail because the transform(Publisher.getPublishedBooks) call will actually return an Optional<Optional<Publisher>>.
It seems fairly reasonable to have a transform()-like method on Optional that would accept a function which returns an Optional. It would act exactly like the current implementation except that it simply would not wrap the result of the function in an Optional. The implementation (for Present) might read:
public abstract <V> Optional<V> optionalTransform(Function<? super T, Optional<V>> function) {
return function.apply(reference);
}
The implementation for Absent is unchanged from transform:
public abstract <V> Optional<V> optionalTransform(Function<? super T, Optional<V>> function) {
checkNotNull(function);
return Optional.absent();
}
It would also be nice if there were a way to handle methods that return null as opposed to Optional for working with legacy objects. Such a method would be like transform but simply call Optional.fromNullable on the result of the function.
I'm curious if anyone else has run into this annoyance and found nice workarounds (which don't involve writing your own Optional class). I'd also love to hear from the Guava team or be pointed to discussions related to the issue (I didn't find any in my searching).
You are looking for some Monad, but Guava's Optional (as opposite to for example Scala's Option) is just a Functor.
What the hell is a Functor?!
Functor and Monad are a kind of box, a context that wraps some value.
Functor containing some value of type A knows how to apply function A => B and put the result back into Functor. For example: get something out of Optional, transform, and wrap back into Optional.
In functional programming languages such method is often named 'map'.
Mona.. what?
Monad is almost the same thing as Functor, except that it consumes function returning value wrapped in Monad (A => Monad, for example Int => Optional).
This magic Monad's method is often called 'flatMap'.
Here you can find really awesome explanations for fundamental FP terms: http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html
Functors & Monads are coming!
Optional from Java 8 can be classified as both Functor (http://docs.oracle.com/javase/8/docs/api/java/util/Optional.html#map-java.util.function.Function-) and Monad (http://docs.oracle.com/javase/8/docs/api/java/util/Optional.html#flatMap-java.util.function.Function-).
Nice mon(ad)olog, Marcin, but how can I solve my particular problem?
I'm currently working on a project that uses Java 6 and yesterday I write some helper class, called 'Optionals', which saved me a lot of time.
It provides some helper method, that allows me to turn Optional into Monads (flatMap).
Here is the code: https://gist.github.com/mkubala/046ae20946411f80ac52
Because my project's codebase still uses nulls as a return value, I introduced Optionals.lift(Function), which can be used to wrapping results into the Optional.
Why lifting result into Optional?
To avoid situation when function passed into transform might return null and whole expression would return "present of null" (which by the way is not possible with Guava's Optional, because of this postcondition -> see line #71 of https://code.google.com/p/guava-libraries/source/browse/guava/src/com/google/common/base/Present.java?r=0823847e96b1d082e94f06327cf218e418fe2228#71).
Couple of examples
Let's assume that findEntity() returns an Optional and Entity.getDecimalField(..) may return BigDecimal or null:
Optional<BigDecimal> maybeDecimalValue = Optionals.flatMap(
findEntity(),
new Function<Entity, Optional<BigDecimal>> () {
#Override
public Optional<BigDecimal> apply(Entity input) {
return Optional.fromNullable(input.getDecimalField(..));
}
}
);
Yet another example, assuming that I already have some Function, which extracts decimal values from Entities, and may return nulls:
Function<Entity, Decimal> extractDecimal = .. // extracts decimal value or null
Optional<BigDecimal> maybeDecimalValue = Optionals.flatMap(
findEntity(),
Optionals.lift(extractDecimal)
);
And last, but not least - your use case as an example:
Optional<Publisher> maybePublisher = Optionals.flatMap(findBook(id), Optionals.lift(Book.getPublisher));
// Assuming that getPublishedBooks may return null..
Optional<List<Book>> maybePublishedBooks = Optionals.flatMap(maybePublisher, Optionals.lift(Publisher.getPublishedBooks));
// ..or simpler, in case when getPublishedBooks never returns null
Optional<List<Book>> maybePublishedBooks2 = maybePublisher.transform(Publisher.getPublishedBooks);
// as a one-liner:
Optionals.flatMap(maybePublisher, Optionals.lift(Publisher.getPublishedBooks)).transform(Publisher.getPublishedBooks);
You probably figured that out, but you could add .or(Optional.absent) after every transformation that returns Optional (in your case after .transform(Book.getPublisher) reducing Optional<Optional<T>> to Optional<T>:
Optional<List<Book>> publishedBooks = findBook(id).transform(Book.getPublisher).
or(Optional.absent()).transform(Publisher.getPublishedBooks);
Unfortunately, the type of Optional.absent cannot be inferred here, so the code actually becomes:
Optional<List<Book>> publishedBooks = book.transform(Book.getPublisher).
or(Optional.<Publisher> absent()).transform(Publisher.getPublishedBoooks);
Not too convenient but there doesn't seem to be any other way.
Possibly a question which has been asked before, but as usual the second you mention the word generic you get a thousand answers explaining type erasure. I went through that phase long ago and know now a lot about generics and their use, but this situation is a slightly more subtle one.
I have a container representing a cell of data in an spreadsheet, which actually stores the data in two formats: as a string for display, but also in another format, dependent on the data (stored as object). The cell also holds a transformer which converts between the type, and also does validity checks for type (e.g. an IntegerTransformer checks if the string is a valid integer, and if it is returns an Integer to store and vice versa).
The cell itself is not typed as I want to be able to change the format (e.g. change the secondary format to float instead of integer, or to raw string) without having to rebuild the cell object with a new type. a previous attempt did use generic types but unable to change the type once defined the coding got very bulky with a lot of reflection.
The question is: how do I get the data out of my Cell in a typed way? I experimented and found that using a generic type could be done with a method even though no constraint was defined
public class Cell {
private String stringVal;
private Object valVal;
private Transformer<?> trans;
private Class<?> valClass;
public String getStringVal(){
return stringVal;
}
public boolean setStringVal(){
//this not only set the value, but checks it with the transformer that it meets constraints and updates valVal too
}
public <T> T getValVal(){
return (T) valVal;
//This works, but I don't understand why
}
}
The bit that puts me off is: that is ? it can't be casting anything, there is no input of type T which constrains it to match anything, actually it doesn't really say anything anywhere. Having a return type of Object does nothing but give casting complications everywhere.
In my test I set a Double value, it stored the Double (as an object), and when i did Double testdou = testCell.getValVal(); it instantly worked, without even an unchecked cast warning. however, when i did String teststr = testCell.getValVal() I got a ClassCastException. Unsurprising really.
There are two views I see on this:
One: using an undefined Cast to seems to be nothing more than a bodge way to put the cast inside the method rather than outside after it returns. It is very neat from a user point of view, but the user of the method has to worry about using the right calls: all this is doing is hiding complex warnings and checks until runtime, but seems to work.
The second view is: I don't like this code: it isn't clean, it isn't the sort of code quality I normaly pride myself in writing. Code should be correct, not just working. Errors should be caught and handled, and anticipated, interfaces should be foolproof even if the only expecter user is myself, and I always prefer a flexible generic and reusable technique to an awkward one off. The problem is: is there any normal way to do this? Is this a sneaky way to achieve the typeless, all accepting ArrayList which returns whatever you want without casting? or is there something I'm missing here. Something tells me I shouldn't trust this code!
perhaps more of a philosophical question than I intended but I guess that's what I'm asking.
edit: further testing.
I tried the following two interesting snippets:
public <T> T getTypedElem() {
T output = (T) this.typedElem;
System.out.println(output.getClass());
return output;
}
public <T> T getTypedElem() {
T output = null;
try {
output = (T) this.typedElem;
System.out.println(output.getClass());
} catch (ClassCastException e) {
System.out.println("class cast caught");
return null;
}
return output;
}
When assigning a double to typedElem and trying to put it into a String I get an exception NOT on the cast to , but on the return, and the second snippet does not protect. The output from the getClass is java.lang.Double, suggesting that is being dynamically inferred from typedElem, but that compiler level type checks are just forced out of the way.
As a note for the debate: there is also a function for getting the valClass, meaning it's possible to do an assignability check at runtime.
Edit2: result
After thinking about the options I've gone with two solutions: one the lightweight solution, but annotated the function as #depreciated, and second the solution where you pass it the class you want to try to cast it as. this way it's a choice depending on the situation.
You could try type tokens:
public <T> T getValue(Class<T> cls) {
if (valVal == null) return null;
else {
if (cls.isInstance(valVal)) return cls.cast(valVal);
return null;
}
}
Note, that this does not do any conversion (i.e., you cannot use this method to extract a Double, if valVal is an instance of Float or Integer).
You should get, btw., a compiler warning about your definition of getValVal. This is, because the cast cannot be checked at run-time (Java generics work by "erasure", which essentially means, that the generic type parameters are forgotten after compilation), so the generated code is more like:
public Object getValVal() {
return valVal;
}
As you are discovering, there is a limit to what can be expressed using Java's type system, even with generics. Sometimes there are relationships between the types of certain values which you would like to assert using type declarations, but you can't (or perhaps you can, at the cost of excess complexity and long, verbose code). I think the sample code in this post (question and answers) is a good illustration of that.
In this case, the Java compiler could do more type checking if you stored the object/string representation inside the "transformer". (Perhaps you'll have to rethink what it is: maybe it's not just a "transformer".) Put a generic bound on your base Transformer class, and make that same bound the type of the "object".
As far as getting the value out of the cell, there's no way that compiler type checking will help you there, since the value can be of different types (and you don't know at compile time what type of object will be stored in a given cell).
I believe you could also do something similar to:
public <T> void setObject(Transformer<T> transformer, T object) {}
If the only way to set the transformer and object is through that method, compiler type checking on the arguments will prevent an incompatible transformer/object pair from going into a cell.
If I understand what you're doing, the type of Transformer which you use is determined solely by the type of object which the cell is holding, is that right? If so, rather than setting the transformer/object together, I would provide a setter for the object only, and do a hash lookup to find the appropriate transformer (using the object type as key). The hash lookup could be done every time the value is set, or when it is converted to a String. Either way would work.
This would naturally make it impossible for the wrong type of Transformer to be passed in.
I think you are a static-typed guy, but lemme try: have you thought about using a dynamic language like groovy for that part?
From your description it seems to me like types are more getting in the way than helping anything.
In groovy you can let the Cell.valVal be dynamic typed and get an easy transformation around:
class Cell {
String val
def valVal
}
def cell = new Cell(val:"10.0")
cell.valVal = cell.val as BigDecimal
BigDecimal valVal = cell.valVal
assert valVal.class == BigDecimal
assert valVal == 10.0
cell.val = "20"
cell.valVal = cell.val as Integer
Integer valVal2 = cell.valVal
assert valVal2.class == Integer
assert valVal2 == 20
Where as it's everything needed for the most common transformations. You can add yours too.
If needing to transform other blocks of code, note that java's syntax is valid groovy syntax, except for the do { ... } while() block
While trying to cast the result of a context.lookup() call in my portal application, I'm getting a ClassCastException for two out of three attempts at casting different results.
After some research I think this: http://wiki.sdn.sap.com/wiki/display/TechTSG/%28AS+Java%29+ClassCastException+Occurs+After+Lookup+Operation holds the answer, but it doesn't explain really how to carry out the two steps.
This code works for fetching the details of an iView, from its path stored in list :
IiView transView1 = (IiView) context.lookup(list.get(i).toString());
but when fetching details of a workset like this:
IPcdContext attrSet = (IPcdContext) context.lookup(list.get(i).toString());
I get a ClassCastException. Any help or explanation as to why I get this error would be greatly appreciated!
edit: This is what the code is based on: http://www.sdn.sap.com/irj/scn/go/portal/prtroot/docs/library/uuid/6112ecb7-0a01-0010-ef90-941c70c9e401?overridelayout=true
edit2: The object I get back from context.lookup is com.sapportals.portal.pcd.pcm.roles.PortalWorkset which I can't find documentation on.
If context.lookup returns you a PortalWorkset, then there's no way to "get round" the ClassCastException.
Casting does not convert an object to a different class - it's merely a way for you to tell the compiler that you're sure it's a more specific class than its current declared type. In this case, you're saying "I realise that the lookup() method is declared to return Object, but when I call it in this particular context I'm sure that it will always specifically return an IPcdContext object." Your assumption here turned out not to hold, and the program correctly signals this by throwing the exception.
There are potential two causes to your problem:
Your assumption is correct in general, but due to a logic bug you're not passing in the string you expect to the lookup method, and so are getting the wrong thing back altogether. In this case, ensure that the parameter passed to the method is always correct.
Your assumption is incorrect, and you might not always get an IPcdContext back. In this case, you'll need to decide what to do with other objects that are returned, and deal with them appropriately (you can use the instanceof operator to check the class of the returned object).
In any case, whenever you do a cast it's usually beneficial to check that it will succeed first, with an idiom like:
IPcdContext context;
Object obj = context.lookup("foo");
if (obj instanceof IPcdContext) {
context = (IPcdContext)obj;
}
else {
// You got back something else. What to do?
}