Why to check all conditions before proceeding? - java

Hi I am a beginner to programming. I am trying to learn Android development from udacity.
Cursor cur = someFunction();
if(cur != null){
Intent intent = new Intent(getActivity(), two.class);
intent.setData(cur.getLong(2));
startActivity(intent)
}
Now in two class.
Intent intent = getActivity.getIntent();
if(intent != null){
mString = intent.getDataString();
}
if(null != mString){
mTextView.setText(mString);
}
I was just wondering why do we require so many ifs in this code. The if in first piece of code is fine.
When the second activity was called from first activity. Why do we need to check if the intent is null? Since it is the only entry point to the second activity.
And why do we again need to check if the string is null before assigning it to Text View?

Just because you see it in some code, that doesn't mean it's required.
The check for null on the first condition isn't necessary. The code here looks like it's being very paranoid that getIntent() might return null.
In the second condition, there is nothing that's telling the compiler that there is a guarantee that the return string will definitely not be null. In fact, the documentation states that it may return null, so it's safe to always check. You can put a null string into a TextView, but that isn't necessarily what's desired. It's hard to tell without context.

Because if you don't check if something is null and try to invoke a method on it, it will cause a NullPointerException. That's why only after you've confirmed that the Intent is not null, you can call the method
intent.getDataString();

Related

DialogFragment - show() method

I would like to see DialogFragment after pressing the button, I have two code snippets:
First:
if (view.equals(b1)) {
Fragment2 fr2 = new Fragment2();
fr2.show(manager, "addCity");
}
I don't understand why this tag is in the show () method, since it has no effect on program change.
Second:
Fragment fr = manager.findFragmentByTag("addCity");
if (view.equals(b1)) {
if (fr != null) {
manager.beginTransaction().remove(fr).commit();
}
Fragment2 fr2 = new Fragment2();
fr2.show(manager, "addCity");
}
In the second example, I don't understand what this line of code is for:
Fragment fr = manager.findFragmentByTag("addCity");
Since the reference variable fr will always be null because there is currently no fragment under the name of such a tag.
In addition, why does this condition appear, since just the previous change fr will always be null, so this if will never come true.
if (fr != null) {
manager.beginTransaction().remove(fr).commit();
}
When you use show(manager, "addCity"), then second parameter is the tag for the Fragment. By using findFragmentByTag() with the same tag, you're looking to see if the DialogFragment already exists and, if it does (fr != null), then remove it.
This is very defensive code, probably made in an attempt to avoid users very, very quickly double tapping the button. However, because it doesn't use showNow() (instead of show()), it actually doesn't do a good job at this because show() is asynchronous.
In general, you don't need this code at all - just call show() without any of the ceremony, using whatever tag you want (the tag only matters if you're later trying to use findFragmentByTag() to retrieve your DialogFragment after the fact).
But if you do want to be defensive and avoid even the extremely rare chance that the user opens up two dialogs, then you need to
1) Use showNow() instead of show() so that the FragmentManager is immediately updated, ensuring that findFragmentByTag() actually does return the Fragment in that case
2) Instead of removing and then calling show() again, just don't call show() if it already being shown - you're just doing extra work.
This would mean your code would look like
if (view.equals(b1)) {
Fragment existingDialog = manager.findFragmentByTag("addCity");
// Only add a new dialog if it isn't already present.
if (existingDialog == null) {
Fragment2 fr2 = new Fragment2();
fr2.showAll(manager, "addCity");
}
}

Method invocation 'extras' may produce NullPointerException [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
Why does this cause the error?
if (extras != null) {
if (extras.getString("ActionBar") != null) {
if (extras.getString("ActionBar").equals("NO")) {
if (bar != null) bar.setDisplayHomeAsUpEnabled(false);
}
}
}
I check to make sure that it is not null first.
You are calling extras.getString("ActionBar") twice. Once you check the returned value against null (but never use it) and once you use it without checking it against null. Now, maybe the contract of that function says that if it is called with identical arguments, it will always return identical values, but this need not be the case and your IDE probably doesn't know.
You should store the return value in a (preferably final) variable, then the warning should go away.
if (extras != null) {
final String actbar = extras.getString("ActionBar");
if (actbar != null) {
if (actbar.equals("NO")) {
// ...
}
}
}
This might also be a performance advantage because you don't need to do getString's work twice.
Anyway, if your code is full of such massive aggregations of if (o != null) { … } checks, this might be an indication of code smell.
You get the warning because you may not receive any bundle (from the sender activity e.g) since you don't initialize it in the current context (or activity). So in this case, if you don't check if extras is null (and extras was in deed equal to null), this line:
if (extras.getString("ActionBar") != null)
would throw a NullPointerException. Therefore, you must check if extras is null first to avoid any potential crash.

java dereferencing possible null pointer

In my code I get the above warning. Here is the part of the code where I get it,
try {
fileFile = new File(Main.class.getProtectionDomain().getCodeSource().getLocation().toURI());
} catch (URISyntaxException | NullPointerException e) {
}
finally {
if (fileFile.getPath()!= null){
strPathName = fileFile.getPath();
}
if (fileFile.getName() != null){
strFileName = fileFile.getName();
}
}
The line if (fileFile.getPath()!= null){ is the one with the warning.
This code is not part of the Main class. It's in another class in another class file in the same package.
I'm not very experienced with programming but I believe I did nearly everything to prevent or catch a null pointer exception. Why do I still getting it and what can I do to get rid of it? Thanks for your help.
After reading all your hints I solved it. Here is the complete code:
public static ArrayList<String> getCurrentPath() {
File fileFile;
String strPathName, strFileName;
ArrayList<String> arrPathFileName;
strFileName = null;
strPathName = null;
try {
fileFile = new File(Main.class.getProtectionDomain().getCodeSource().getLocation().toURI());
if (fileFile.getPath()!= null){
strPathName = fileFile.getPath();
}
if (fileFile.getName() != null){
strFileName = fileFile.getName();
}
} catch (URISyntaxException use) {
}
arrPathFileName = new ArrayList<>();
arrPathFileName.add(strPathName);
arrPathFileName.add(strFileName);
return arrPathFileName;
}
As already mentioned I simply put the if statements into the try block and removed the finally block.
BTW is also tried to combine both if blocks into one that way:
if (fileFile != null){
strPathName = fileFile.getPath();
strFileName = fileFile.getName();
}
But that produced a warning that fileFile will never become null. (what was my point of view from the beginning and so the warning "dereferencing possible null pointer" was really confusing me.)
So if you throw an exception on your first line, your variable will not be assigned to a File, and will retain it's previous value (null if not formerly assigned). Your exception is caught, and then you continue to use that unassigned variable. Hence the warning. See the commented code below.
try {
fileFile = // exception thrown. Variable not assigned
} catch (URISyntaxException | NullPointerException e) {
// exception caught
}
finally {
// unassigned variable used here...
if (fileFile.getPath()!= null){
strPathName = fileFile.getPath();
}
if (fileFile.getName() != null){
strFileName = fileFile.getName();
}
}
I would rather scope and use the variable within the try block, if at all practical. In your finally block, you need to be as careful as you can, since you could have come to it from most anywhere in your try block.
As an aside, this:
Main.class.getProtectionDomain().getCodeSource().getLocation().toURI();
will cause you enormous problems if you do get an NPE. Which of the above resolved to null ? I would perhaps be more explicit, such that you can check for nulls from each invocation and unambiguously determine which invocation gave you a null. Tiresome ? Unfortunately so.
A "null pointer dereference" is computer speak for trying to call a method on a null value. It's a little more complicated, but you said you were a novice, so I wanted to keep it simple.
Let's see an example:
String s = null;
s = s.toUpperCase();
This is a simple example of what a null pointer dereference is. s is a null reference (its value is null), when we derefrence is (get the value of it) we have null, when we call toUpperCase() on null, something goes horribly wrong because null doesn't have any methods, at all! Java throws a NullPointerException to be specific.
Now, back to your code, because fileFile is assigned in the try-block I assume it was set to null before it to avoid Java yelling about an uninitialized variable. (This is all fine and correct.) In this try-block, if any of the exceptions for your catch-block occur it will stop the try-block (meaning fileFile will not get a new value, meaning it will still be null).
Now you'll notice the warning is possible null pointer dereference. That means it won't necessarily be null, but could be! (In my above example, it's always a null pointer dereference for comparison.) Specifically, if the catch catches an exception it will be null.
To be clear, the issue is this: fileFile.getPath(). It's like saying it might be null.getPath(), gross. It looks like you were trying to avoid the null pointer issue, what you should have done was if (fileFile != null) { instead. Then inside of the if do what you want.
Also, because it seems like you included it to avoid this warning, I would seriously remove the NullPointerException from the catch-block. That's not helping you avoid the warning. If you want me to explain more why it's bad you can leave a comment and I will, otherwise just take my word for it, it's not helping you.

How do I initialise a variable in this case?

I'm starting an intent where the activity started depends on whether a device is a group owner or just a joined peer. At the moment, instructIntent is not initialised. Am I supposed to make it null as Eclipse suggests? Or is there some more professional, Java code style way of handling this?
Intent instructIntent;
if (info.groupFormed && info.isGroupOwner) {
Log.d(WiFiDirectActivity.TAG, "DeviceDetailFragment_onCreateView: btn_ready pressed on host");
instructIntent = new Intent(getActivity(), LeaderActivity.class);
} else if (info.groupFormed) {
Log.d(WiFiDirectActivity.TAG, "DeviceDetailFragment_onCreateView: btn_ready pressed on client");
instructIntent = new Intent(getActivity(), MusicianActivity.class);
}
instructIntent.putExtra(Intent.EXTRA_TEXT, "Play");
instructIntent.putExtra(MusicService.EXTRAS_GROUP_OWNER_ADDRESS, info.groupOwnerAddress.getHostAddress());
instructIntent.putExtra(MusicService.EXTRAS_GROUP_OWNER_PORT, 8080);
startActivity(instructIntent);
Making it null won't help. The real problem is if info.groupFormed is false, you won't have a valid value in instructIntent. But even if you initialize it to null, it still won't be valid. That means it will throw an exception when you call putExtra in it. A better way is to do:
if(info.groupFormed){
if(info.isGroupOwner){
instructIntent = new Intent(getActivity(), LeaderActivity.class);
}
else{
instructIntent = new Intent(getActivity(), MusicianActivity.class);
}
//all of your putExtra and startIntent calls here
}
Notice that all branches that go to the put and start calls on the intent will create a new intent. This way you won't have a null or unitnitialized variable trying to call a member function.
Any variable declared in java should be given value before using it. In the code given above there is possibility that we will not assign any value to the instructIntent variable if both both if and else if condition is not satisfied.
So you have to initialize instructIntent to null as follows.
Intent instructIntent = null;

NullPointerException, logical shortcut

Here is a simple code snippet and I cannot figure out why does it throw a NullPointerException.
String lastGroup = "";
menuTevekenysegekGrouped = new ArrayList<MenuElem>();
for(MenuElem me : menuA) {
// double checked that me objects are never null
// double checked that menuA is never null
if(me.getGroup() != null && !me.getGroup().equals(lastGroup)) { /* NPE!!! */
lastGroup = me.getGroup();
MenuElem separ = new MenuElem();
separ.setCaption(lastGroup);
separ.setGroupHead(true);
menuTevekenysegekGrouped.add(separ);
menuTevekenysegekGrouped.add(me);
} else {
menuTevekenysegekGrouped.add(me);
}
}
In the first iteration the me.getGroup() returns null. So the first operand of the && is false and second operand should not evaluate according to the JLS, as far as I know. However when I debug the code I get NPE from the marked line. I'd like to know why. (Using JRockit 1.6.0_05 if it matters..)
Are you sure that me itself is not, in fact, null?
From your code (without the stacktrace I have to guess), the following may be null and be the cause: menuA or me or menuTevekenysegekGrouped. And some of the values returned from the methods/or used in the methods may also be null, but it's hard to know...
If me is not null, then the only other object that can be null in the above snippet is menuTevekenysegekGrouped. Add a check before first using it to ensure that it's not null.
The repeated calls to me.getGroup() would bug me enough to pull them out into a local variable:
String lastGroup = "";
for(MenuElem me : menuA) {
String thisGroup = me.getGroup();
if(thisGroup != null && !thisGroup.equals(lastGroup)) {
lastGroup = thisGroup;
MenuElem separ = new MenuElem();
separ.setCaption(lastGroup);
separ.setGroupHead(true);
menuTevekenysegekGrouped.add(separ);
menuTevekenysegekGrouped.add(me);
} else {
menuTevekenysegekGrouped.add(me);
}
}
This is only going to fix your problem if in fact me.getGroup() returns different values (sometimes null) on multiple calls with the same me, but it might make it easier to debug, and certainly makes it easier to read.

Categories

Resources