I often find myself searching for statements of a particular form in Java. Say I've written a simple function to express an idiom, such as "take this value, or a default value if it's null"
/** return a if not null, the default otherwise. */
public static <T> T notNull(T a, T def) {
if (a == null)
return def;
else
return a;
}
Now if I've written this, I want to look for cases in my code where it can be used to simplify, for instance
(some.longExpressionWhichMayBeNull() ? "default string" : some.longExpressionWhichMayBeNull())
The problem is that it's pretty tricky to write a regular expression that matches java syntax. It can be done, of course, but it's easy to get wrong. It's hard to get regular expressions to ignore whitespace in all the right locations always accurately figure out where strings start and stop, know the difference between a cast and a function call etc.
It also seems a bit wasteful, since we already have a java parser, which does that already.
So my question is: is there some Java syntax aware alternative to regular expressions for searching for particular (sub-)expressions?
You'd probably need to build an abstract syntax tree of the Java source file(s) and then analyse that. Might be possibly to leverage PMD (http://pmd.sourceforge.net/) and write a custom rule (http://pmd.sourceforge.net/pmd-5.0.5/howtowritearule.html) to detect and flag expressions that could be optimised as you describe.
Related
I have been experimenting with instanceof in my Java code.
public class Test {
public static void main(String[] args) {
String favoriteFood = "sandwich";
boolean flag = favoriteFood instanceof StringBuilder; //incompatible types
}
}
I get an error from flag because String cannot be cast to StringBuilder. I understand that testing a String to check if it is an instance of StringBuilder is illogical because Strings can never be cast as StringBuilders. I also understand the benefits of failing fast. However, is there any way to still run this test and return false? I have looked at related posts, but they have more to do with why there is an error than what to do about it.
(I know there is no practical need to do this. I just want to know if this can be done. If yes, then how? If not, then why not?)
The simplest approach is:
boolean flag = false;
but if that's unappealing to you for some reason, you can write:
boolean flag = ((Object)favoriteFood) instanceof StringBuilder; // false
and then bribe a coworker to let it past code review.
The answer to If not, then why not? is "because the language spec says so" (see comment by Carlos H.).
And the answer to "why does the language spec say so" is that language definers have this tendency to outlaw constructs that make no sense whenever they can, and this tendency is inspired by their belief that in doing that, they are helping you to write better code.
EDIT
re. "does defining a boolean as (2 + 2 == 5) make any more logical sense than ..." : no, it doesn't, but :
(a) it is impossible (that is, logistically infeasible) for language definers to inventorize all the things that could be written but make no logical sense (*)
(b) this kind of problem boils down to proving the emptiness of a set (e.g. proving that the set of all possible instances of String that are also instances of StringBuilder is empty) and proving the emptiness of a set in general as a problem is NP-hard. Given specific extra information, it might be possible and is sometimes done, e.g. given a type hierarchy that almost literally says "no String can also be a StringBuilder". But in general, that is undoable. Which is why you'll always find cases if only you keep searching hard enough.
(*) For your sense of "logical sense", but what you (/we all) really mean, is really just "good programming practice", one of which would be "avoiding obfuscated ways of writing false". It might seem counterintuitive to you, but logic has no concept of "logical sense". 2+2==5 is just another logical proposition, and it happens to be false. Logic does not complain about falsehoods, it just observes them.
(PS I know I used "makes no sense" too, shouldn't have, but I allowed myself to get carried away.)
I'm new to Java and I couldn't find an answer to it anywhere because i don't even know how to search for it.
I want to define how 2 objects can be added together, so you get a new one like for example you can add String "a" and String "b" to get "ab".
I know this can be done in python by doing self.__add__(self, other).
How can you do this in Java?
The thing you are looking for is called operator overloading. It exists in some languages, however in Java it does not.
The best thing you can do is to define a method add() inside the class and then use it like this:
object1.add(object2);
I know it looks nicer with a + between them, but that would make compiling more complex.
With the exception of java.lang.String being treated as a special case1, Java does not allow you to define the behaviour of + for arbitrary types, or indeed any other operator, as you can in some languages such as C++ or Scala. In other words, Java does not support operator overloading.
Your best bet is to build functions like add &c. Appeal to precedent here: see how the Java guys have done it with BigInteger, for example. Sadly there is no way of defining the precedence of your functions, so you have to use very many parentheses to tell the compiler how you want an expression to be evaluated. It's for this reason that I don't use Java for any serious mathematical applications as the implementation of even a simple equation quickly becomes an unreadable mess2.
1 Which in some ways does more harm than good: e.g. consider 1 + 2 + "Hello" + 3 + 4. This compile time constant expression is a string type with the value 3Hello34.
2 Note that C++ was used to model the gravitational lensing effects of the wormhole in the movie "Interstellar". I challenge anyone to do that in a language that does not support operator overloading! See https://arxiv.org/pdf/1502.03808v1.pdf
Java does not allow you to override operators. String is a special case that does allow this functionality.
What you can do is add an add function like so:
public YourObject add(YourObject yourObject){
return new YourObject(this.propertyToAdd + yourObject.propertyToAdd);
}
Given a string, how can I validate the contents are a valid PCRE within Java? I don't want to use the regex in any way within Java, just validate its contents.
java.util.regex.Pattern is almost good enough, but its javadoc points out how it differs from Perl.
In detail, there's a system with 3 relevant components:
Component A - Generates, among other things, Perl-compliant regular expressions (PCREs) to be evaluated at runtime by some other component capable of executing PCREs (component C). What's "generated" here may be coming from a human.
Component B - Validates that data generated by component A and, if valid, shuttles it over to the runtime (component C).
Component C - Some runtime that evaluates PCREs. This could be a Perl VM, a native process using the PCRE library, Boost.Regex, etc., or something else that can compile/execute a Perl-compliant regular expression.
Now, component B is implemented in Java. As mentioned above, it needs to validate a string potentially containing a PCRE, but does not need to execute it.
How could we do that?
One option would be something like:
public static boolean isValidPCRE(String str) {
try {
Pattern.compile(str);
} catch (PatternSyntaxException e) {
return false;
}
return true;
}
The problem is that java.util.regex.Pattern is designed to work with a regular expression syntax that is not exactly Perl-compliant. The javadoc makes that quite clear.
So, given a string, how can I validate the contents are a valid PCRE within Java?
Note: There are some differences between libPCRE and Perl, but they are pretty minor. To a certain degree, that is true of Java's syntax as well. However, the question still stands.
I'm feeling quite silly for asking this question, but I've already seen this code on two separate corporate codebases and I'm starting to think there's some chunk of ancient java knowledge I'm not aware of.
So, we got this kind of code:
/* Lot of corporate stuff */
if (ClassicUtilsClass.isNotNull(variable)) {
/* Variable handling shenanigans. */
}
Going to our ClassicUtilsClass revealed the implementation of the function:
/* Lot of useful static functions*/
public static isNotNull(Object o) {
return o!=null;
}
public static isNull(Object o) {
return o==null;
}
I read it, scratched my head, looked around the internet, asked colleagues and friends, then laugh at the uselessness of the function. Then I switched jobs and a colleague showed me more or less the same code.
In the same codebase we have the classic "isNullOrEmpty" which does the standard "return object==null || object.size() == 0;", so I can understand having a function to wrap the null comparison... plus something else, but I don't see the point of creating a whole new function for null checking.
I'm losing something here?
There are similar functions in the Objects utility class, called nonNull and isNull. The reason they are provided is to be used as predicates, e.g.
...stream().filter(Objects::nonNull)...
I can't see any reason to use
if (SomeClass.isNotNull(x))
rather than the shorter, clearer
if (x!=null)
There are only a few reasons to implement operators as methods that I can think of.
The first reason is to "profile" how many times the operation is used in an application. Profiling tools count the time spent in methods and the number of times methods are called but they don't track operator usage.
The second reason to implement operators as functions is to use them in functional programming constructs. Operators cannot be passed around using reflection, but methods can, so it is possible to create functional operations (map, reduce, etc) that use reflection and in those cases operators would need to be implemented as methods to be utilized.
A third possible reason to implement the not null operator as a method is to simplify the automated translation of some other programming languages into java. In java primitive types cannot be null so checking if they are null directly using the == operator would cause a compiler error. Java will autobox primitives into objects so they can be used as arguments to methods which accept Object as their argument type. In this case a code translator could translate null checks to method calls without needing to track the variable type.
Maybe the reason could be that in some tests it can be useful to mock ClassicUtilsClass.isNotNull and ClassicUtilsClass.isNull methods to return true or false.
Anyway as you I can't see the point. Different would be a StringUtils.isEmpty by Apache Commons, which returns true if the string is null or equal to ""
Is this a valid (intended) usage of Optional type in Java 8?
String process(String s) {
return Optional.ofNullable(s).orElseGet(this::getDefault);
}
I'll take another swing at this.
Is this a valid usage? Yes, in the narrow sense that it compiles and produces the results that you're expecting.
Is this intended usage? No. Now, sometimes things find usefulness beyond what they were originally for, and if this works out, great. But for Optional, we have found that usually things don't work out very well.
Brian Goetz and I discussed some of the issues with Optional in our JavaOne 2015 talk, API Design With Java 8 Lambdas and Streams:
link to video
link to slides
The primary use of Optional is as follows: (slide 36)
Optional is intended to provide a limited mechanism for library method return types where there is a clear need to represent "no result," and where using null for that is overwhelmingly likely to cause errors.
The ability to chain methods from an Optional is undoubtedly very cool, and in some cases it reduces the clutter from conditional logic. But quite often this doesn't work out. A typical code smell is, instead of the code using method chaining to handle an Optional returned from some method, it creates an Optional from something that's nullable, in order to chain methods and avoid conditionals. Here's an example of that in action (also from our presentation, slide 42):
// BAD
String process(String s) {
return Optional.ofNullable(s).orElseGet(this::getDefault);
}
// GOOD
String process(String s) {
return (s != null) ? s : getDefault();
}
The method that uses Optional is longer, and most people find it more obscure than the conventional code. Not only that, it creates extra garbage for no good reason.
Bottom line: just because you can do something doesn't mean that you should do it.
Since this is more or less an opinion-based question, I'll throw mine in. If you're trying to say
if (id == 1) {
Foo f = new Foo(id, "Bar", "US");
return "Bar".equals(f.getName()) && "US".equals(f.getCountryCode());
} else {
return false;
}
then just say that. Making things "functional" doesn't automatically make things clearer or better. By introducing a needless Optional, a couple lambdas, and some Optional methods that I had to look up, you've made the code more convoluted and difficult to understand. I don't think the designers of Java "intended" for people to use Optional to help make code more obscure.
EDIT: After reading some responses, I think it's worth adding some comments. This is not a functional programming idiom I'm familiar with, which would make it harder to understand. The idioms I am familiar with mostly involve Java streams, or (in other languages) functional idioms applied to multiple values in arrays or lists or other collections of multiple values. In those cases, once you get past the unfamiliarity, the functional syntax can be seen as an improvement because it allows some details to be hidden (loop indexes, iterators, running pointers, accumulator variables). So overall, it can simplify things. This example, by itself, doesn't do any such simplification.
However, some of the Optional features are useful in stream contexts. Suppose we had a parseInt() method that returns an Optional<Integer>, which is empty if the input string is invalid. (Java 8 really should have provided this.) This would make it easy to take an array of strings and produce an array of integers in which the strings that don't parse are simply eliminated from the result--use parseInt in a stream map(), and use a stream filter to filter out the empty Optionals. (I've seen multiple StackOverflow questions asking how to do this.) If you want to keep only the positive values, you could use an Optional.filter() to change the nonpositives to Optional.empty() before using the stream filter (although in this case, you could add another stream filter afterwards, but in a more complex case the Optional filter could be more useful). That's what I see as the main benefit of Optional from a functional standpoint. It allows you to work with a collection of values all at once, by giving you a way to represent "non-values" and write a function that will still work with them. So I guess the main use of Optional, besides a replacement for null, would be to represent empty spaces in a sequence of values while you're applying functions to the entire sequence as a whole.
Asking whether it's "valid" is rather opinion-based, but as to whether it's the intended use case: no, it's not.
Brian Goetz, Oracle's language architect for Java, has stated that the use case for Optional is for when you need a "no value" marker, and when using null for this is likely to cause errors. Specifically, if a reasonable user of your method is not likely to consider the possibility that its result is null, then you should use Optional. It was explicitly not intended to be a general "Maybe"-type object, as you're using it here.
In your case, the method that returns the Optional is private. That means it can only be used by the implementers of the class, and you can assume that they have good knowledge of the class' methods — including which of them may return null. Since there's no reasonable risk of confusion, Brian Goetz would (probably) say that he would not consider this a valid use case.
Its a little contrived, but 'valid' (as in 'syntactically') , but as #yshavit pointed to, it was intended for use in library development.
Previous answer was due to FP code being difficult to read. Below is commented(a little verbose, b/c that is the javadoc comments) but still. Much easier to read IMHO. (2nd is no-comments, and at least alignment to help readability)
private boolean isFooValid(final Integer id) {
return getFoo(id)
// filter if 'f' matches the predicate, return Optional w/f if true, empty Optional if false
.filter(f -> "Bar".equals(f.getName()) && "US".equals(f.getCountryCode()))
// If a value is present, apply the provided mapping function to it,
// If non-null, return an Optional describing the result.
.map(f -> true)
// Return the value if present, otherwise return other.
.orElse(false);
}
Or at least line it up so its more apparent what is going on and easier to read.
private boolean isFooValid(final Integer id) {
return getFoo(id)
.filter(f -> "Bar".equals(f.getName()) && "US".equals(f.getCountryCode()))
.map(f -> true)
.orElse(false);
}