I'm having a super weird behavior from a code that I was testing. The test I wrote was to see the behavior of the class if the Android returned an empty package name. After some debugging, I found this (consider that packageName is empty):
val resultFromKotlin = packageName.isNullOrEmpty()
val resultFromJava = StringUtils.isEmpty(packageName)
Is this expected? Can someone tell what the deal with this?
ps1.: In the picture above, Android Studio was complaining of isNullOrEmpty saying that could be simplified since packageName can't be null at that point.
ps2.: For references:
The StringUtils class is written in Java as follow:
public static boolean isEmpty(String str) {
return str == null || TextUtils.isEmpty(str.trim());
}
TextUtils is also from Java, but it's part of Android library:
public static boolean isEmpty(#Nullable CharSequence str) {
return str == null || str.length() == 0;
}
This is how kotlin implements it's extension method:
public inline fun CharSequence?.isNullOrEmpty(): Boolean {
contract {
returns(false) implies (this#isNullOrEmpty != null)
}
return this == null || this.length == 0
}
EDIT 08/11/2018:
Just for clarification, my problem is the wrong value returned from Java, not searching for an equivalence in the test, also:
This seems to be a problem with TextUtils when running tests.
If you are running unit tests, Android frameworks methods are mocked, and this one in particular returns false. Use instrumentation tests to run against a full Android runtime.
Here is where the issue is discussed.
I have tested manually by recreating the function, and it is returning true.
I would suggest using Apache Commons StringUtils implementation: StringUtils
Related
I am using to checking input parameters with the java boilerplate like this on the top of the method:
public static Boolean filesExist(String file1, String file2, String file3 ... ) {
if (file1 == null || file2 == null || file3 == null ||...) {
throw new IllegalArgumentException();
}
if (another_param == null) {
throw new NullPointerException();
}
}
However, I was reading up on Java 8's optionals and noticed we could do something like this instead:
Optional.ofNullable(file1).orElseThrow(IllegalArgumentException::new);
Optional.ofNullable(file2).orElseThrow(IllegalArgumentException::new);
Optional.ofNullable(another_param).orElseThrow(NullPointerException::new);
...
So my question is is there any downside of doing it the second way, I feel that it looks a bit cleaner to me.
For input validation, use Objects.requireNonNull instead:
public static Boolean filesExist(String file1, String file2, String file3 ... ) {
Objects.requireNonNull(file1);
Objects.requireNonNull(file2, "custom message");
}
It is more concise, communicates intention more clearly and does not create an additional Optional object. It throws a NullPointerException, though.
There is no downside of doing it this way and the code would work fine,but Optional were introduced to serve a different purpose.For example ,you can use Optional in the method signature in your interface in-order to clearly communicate your clients that the value returned by your method is "Optional".This way your clients don't have to do the guess work.
No, there is no downside of doing the second way. Both do the same thing but in a different way. Optional is a new feature which was added in Java 8.
Since Java's assert keyword is fundamentally broken on Android, I am about to implement an assertion class that can be configured to check assertions in release builds as well.
Now I can do something like:
MyAssertion.assert(a != 2)
which throws an AssertionException when the expression is false. But how can I get a String representation of the expression to pass to the error message?
The only way is to add a String parameter to your assert method:
MyAssertion.assert(a != 2, "a must not be equal to 2");
What you get as input for assert is either true or false so you can't build a representative String from that.
Otherwise, you could implement assert like this:
MyAssertion.assertNotEquals(a, 2);
When this fails, you know that it is because what you tested was equal to 2 and you can build an informative message (though you won't know what specifically was equal to 2).
If you want to somehow be able to construct a meaningful message from an assertion, the only way I see it possible is to construct an String expression, ask the JavaScript engine to evaluate it and build a message if the expression evaluates to false. Note that will degrade a lot performance as launching the JavaScript engine takes a lot of time. This could be solved with a mechanism of disabling assertions in production.
The following is an example of that. Note that I'm using the new Java 8 Nashorn JavaScript engine but this should work with the older Rhino.
Usage example:
int value = 3;
String str = "test";
Assertions.assertTrue("$1 == 3", value);
Assertions.assertTrue("$1 == 3 && $2 == 'test'", value, str);
Assertions.assertTrue("$1 == 4 && $2 == 'test'", value, str);
This will throw for the 3rd assertion:
An assertion has failed: 3 == 4 && 'test' == 'test'
The idea is that you can write any JavaScript-friendly expression that can be evaluated to a boolean. The placeholders $i will be replaced by what's given as a parameter to the method ($1 will be replaced by the first parameter, etc.).
This is the class. It could be improved (handle error conditions like not enough parameters, etc.) but this should be enough to get you started.
public final class Assertions {
private static final ScriptEngine ENGINE = new ScriptEngineManager().getEngineByName("nashorn");
private Assertions() { }
public static void assertTrue(String expression, Object... values) {
for (int i = 0; i < values.length; i++) {
ENGINE.put("$" + (i+1), values[i]);
}
try {
boolean pass = (Boolean) ENGINE.eval(expression);
if (!pass) {
for (int i = 0; i < values.length; i++) {
expression = expression.replace("$" + (i+1), stringRepresentation(values[i]));
}
throw new AssertionError("An assertion has failed: " + expression);
}
} catch (ScriptException e) {
throw new InternalError(e);
} finally {
for (int i = 0; i < values.length; i++) {
ENGINE.getBindings(ScriptContext.ENGINE_SCOPE).remove("$" + (i+1));
}
}
}
private static String stringRepresentation(Object o) {
if (o instanceof String) {
return "'" + o + "'";
}
return o.toString();
}
}
Annotation processing can do this. You'd create an annotation e.g. #InlineAssertExpressions. Then write a processor that parses your source file and creates a string representing the expression and adds it to the call to your assert method, which you could overload to take an optional String argument. This way is quite optimal performance-wise, since the inlining happens compile-time. Annotation processing is a bit overlooked, but I think this is a great use for it.
(1) Simple to use, but hard to implement. Java 8 required. You can use lambda expressions:
Assert.isTrue(() => a != 2)
On evaluation failure your implementation of Assert.isTrue method should repeat all steps as IDEs do - (a) discover bytecode of lambda class, (b) decompile e.g. with JAD, (c) discover sources if available
(2) Simple to use, simple to implement, but does not fully cover your requirements. You can use CodeStyle rules to check & force correct assertions usage. One regexp will check there is no single-argument assertions, the second (using regexp back refs) will check code and text description are similar.
(3) Simple to use, simple to implement, but relies on your build system. You can automatically check and fix source code during project build.
E.g. for Maven build system you can create your own plugin to check and fix assertions usage in sources on process-sources stage.
I think you cannot access the internal java expression, which was passed to method call.
You can, however, use some expression language libraries and do a custom expression handling for your assertion implementation.
Here is a list of some expression language libraries:
http://java-source.net/open-source/expression-languages
Hope that helps :)
I have several substr() calls in my application. Is there any common library, eg by apache, that provides a substring utility which does not throw NPE if the value is null, but then just returns an empty string?
I know I could write it like this, but maybe there is already such in implementation?
public static String substr(String value, int idx) {
return value != null ? value.substr(idx) : "";
}
Take a look at the apache commons StringUtils.substring
An apache commons lang equivalent to your code is
StringUtils.defaultString(StringUtils.substring(value, idx));
I do not think you need a library for that. Just check against null and the length to avoid exceptions.
public static String substr(String value, int idx) {
if (value == null || value.isEmpty() || idx > value.length()) return "";
return value.substr(idx);
}
Simply check the length to avoid an exceptiom
public static String substr(int idx) {
if(value==null||idx>value.length){
return ""; // Exception avoided
}
return value.substr(idx) ;
}
You already coded it, and by definition you cannot make a call on a null object, so the library would do something like what you have written.
Anyway when you know what to do also it is quite simple.
You can put an utility class in your app with substr static method. Search and replace all the calls in the App with the one in utility class.
I am taking this code snippet from K&B practice exams.
public class Later {
public static void main(String[] args) {
boolean earlyExit = new Later().test1(args);
if (earlyExit) assert false; // LINE 5
new Later().test2(args);
}
boolean test1(String[] a) {
if (a.length == 0) return false;
return true;
}
private void test2(String[] a) {
if (a.length == 2) assert false; // LINE 13
}
}
The answer in K&B states that, LINE-5 AND LINE-13 are in-appropriate use of assertions.
I would like to know why. Here is my observation after reading topic of assertion from
K&B.
1.I do understand, LINE 5 is in-appropriate because it is using assertion to validate
command line arguments. Assertions should never be used to validate command line arguments.
2.In answer, it also states that, LINE 13 is also in-appropriate use of assertions. Good practice
in assertions states that, you can use assertions to validate arguments to your private methods. So
my question is why LINE 13 is in-appropriate use of assertions.
Any insights over this will be helpful.
Assertion (assert keyword in java) are used to verify the correctness of an invariant in code, precondition or postcondition. They are used to test your assumption in code to catch inconsistent state and are - usually - an indicator of a bug or a unwanted flow execution.
Assertion are disabled as default because they shouldn't throw in production and asserted code is not executed
public class AssertionTest {
private boolean productionCode(){
System.out.println("Prodution code executed");
return true;
}
private void assertion() {
assert productionCode();
}
}
with assertion enabled output is :
Prodution code executed
and with assertion disabled output is...nothing! so be carefully
Syntax:
assert <boolean expression>; throws an AssertionError if is false
assert <boolean expression> : <expression with value> throws AssertionError with detail message if is false
In your example
private void test2(String[] a) {
if (a.length == 2) assert false; // LINE 13
}
you are using it in a wrong way because the right way is
private void test2(String[] a) {
assert (a.length != 2);
}
means: a MUST have a lenght not equals 2 else is an error
Read here for Oracle documentation.
Assertions are used to check for code invariants. You should never do input validation by using assertions, because usually they are disabled at runtime, that's why LINE 5 is inappropriate.
Q:Assertion advocates that we can use assertion to validate private methods.
A: Yes, you can validate private method's arguments with assertions, because they are not visible to the public - i.e. if assertion fails it means that there is a logic/programmers mistake somewhere in the caller, but I'd recommend using if/else/exceptions constructs. As I said above, you should never validate public methods, because in practice everyone can pass anything to the method and if assertions are disabled bad things will happen :)
I'm a bit new to Guava and it's style. I'm definitely digging it, but one thing I keep tripping over is the order of chained methods. Where I seem to have this problem the most is when using compound Orderings. I have to keep asking myself questions like:
Where does the natural go?
Where does the nullFirst (or last) go?
Which nullsFirst does what? (In the example below, one for host, one for last name, one for first name?)
Here's an example of one that I was just working on. It looks cumbersome, and I'm just not sure if I put it all together right. I have some JUnits to test it, and it seems okay, but there are always those quirky boundary cases.
Ordering<Host> lastNameThenFirstNameOrdering = Ordering.natural().nullsFirst().onResultOf(new Function<Host, String>() {
public String apply(Host host) {
return host.getLastName();
}}).compound(Ordering.natural().nullsFirst().onResultOf(new Function<Host, String>() {
public String apply(Host host) {
return host.getFirstName();
}})).nullsFirst();
As for an actual question: Is there a well-defined rule for how these things get executed? It seems to be last-to-first, but I'm having trouble telling that.
edit: Just wanted to point out the large, ugly code I was trying to replace:
Ordering<Host> ordering2 = new Ordering<Host>() {
public int compare(Host host1, Host host2) {
if (host1 == null || host2 == null) {
return host1 == host2 ? 0 : ((host1 == null) ? -1 : 1);
}
if(host1.getLastName() != null || host2.getLastName() != null){
if (host1.getLastName() == null) {
return -1;
} else if (host2.getLastName() == null) {
return 1;
}
if (host1.getLastName().compareTo(host2.getLastName()) != 0) {
return host1.getLastName().compareTo(host2.getLastName());
}
}
if (host1.getFirstName() == null) {
return -1;
} else if (host2.getFirstName() == null) {
return 1;
}
return host1.getFirstName().compareTo(host2.getFirstName());
}};
I think what you do is correct, but awfully ugly. Try this for readability:
Use an Enum
Move the functions to an enum that implements Function<Host, String>. Each of the enum items can provide it's own implementation.
enum HostFunctions implements Function<Host, String>{
GETFIRSTNAME{
#Override
public String apply(final Host host){
return host.getFirstName();
}
},
GETLASTNAME{
#Override
public String apply(final Host host){
return host.getLastName();
}
}
}
Indent your Code
Now reference those enum functions and indent your code properly. This is what it will look like:
final Ordering<Host> orderingByLastAndFirstName =
Ordering
.natural()
.nullsFirst()
.onResultOf(HostFunctions.GETLASTNAME)
.compound(
Ordering
.natural()
.nullsFirst()
.onResultOf(HostFunctions.GETFIRSTNAME))
.nullsFirst();
I'd say that makes everything much more understandable.
IDE Configuration
Regarding proper indentation (at least if you use Eclipse), see this question:
How to indent the fluent interface
pattern “correctly” with eclipse?
Enums as Functions
Regarding the enum: this is called the enum singleton pattern. The Guava guys use it all over their code base. Read about it on wikipedia or in Effective Java, Item 3. Although those sources both talk about single-item enums, the approach is almost the same here.
Each chaining call is "wrapping" the previous ordering into a new one, so you're right, the execution order can be thought of as "backwards".
I wrote and reviewed the Ordering class and I still regularly have to stop and scratch my head over the correct interleaving of nullsFirst(), and onResultOf() and reverse()!
The following would be my preference for doing this, assuming you must be able to handle null hosts, first names and last names. To me, it seems like a non-null first name and last name ought to be a requirement of the Host class. And you should generally try to avoid allowing collections to contain null objects.
Ordering<Host> lastNameFirstNameOrdering = new Ordering<Host>() {
#Override public int compare(Host left, Host right) {
return ComparisonChain.start()
.compare(left.getLastName(), right.getLastName(), Ordering.natural().nullsFirst())
.compare(left.getFirstName(), right.getFirstName(), Ordering.natural().nullsFirst())
.result();
}
}.nullsFirst();
Alternatively, I'd take an approach similar to Sean's but break things down for readability.
Ordering<Host> lastNameOrder = Ordering.natural().nullsFirst()
.onResultOf(Host.LAST_NAME);
Ordering<Host> firstNameOrder = Ordering.natural().nullsFirst()
.onResultOf(Host.FIRST_NAME);
Ordering<Host> orderingByLastAndFirstName =
lastNameOrder.compound(firstNameOrder).nullsFirst();
Keep in mind that you could also make these individual orderings static final fields of the class, allowing you to easily use them anywhere when sorting like Host.LAST_NAME_ORDER.