Let’s see your first class:
class ligacao {
// ...
public licacao(boolean b){
// ...
Here we have a build error, because the constructor name should be ligacao
, and not licacao
. Also, the naming convention dictates that class names begin with uppercase letters, and disobeying this convention is not a good idea.
A little further down:
filtrar.removeAll(obls);
There is no variable obls
. I think you mean obs
.
Also in this method:
if(b == true){
Please, NEVER compare a boolean expression or variable with == true
or == false
. This is bad programming practice. Instead, just use it like this:
if (b) {
And if I wanted to compare it to false
, just use that:
if (!b) {
The method also has as a return FilteredList
raw without the generic type instead of FilteredList<Person>
. The compiler must be giving some warnings of types rawtypes and unchecked because of that.
Looking where you use the class ligacao
out of it, we have these two places:
new ligacao(b);
ligacao.get(obs(), obs2());
In the first case, the ligacao
newly created will not be used for anything and will be lost to be devoured by the garbage collector. The only effect of this will be to change the value of the static variable b
(that I see no point in being protected
instead of private
). In the second case, the method get
is static. As a conclusion, instances of the class ligacao
are useless, and therefore have no sense of being instantiated. The constructor you used is nothing more than a Setter disguised, and using constructors for that is something hideous. The suggestion in this case would be to eliminate the constructor and use a Setter static:
class Ligacao {
private static boolean b;
public static void setFlag(boolean novoValor) {
b = novoValor;
}
// Na segunda classe:
Ligacao.setFlag(b);
Let’s take a look at the code that came out of second class, and try to track down what the value of b
hers:
carne.setOnAction((Carne) -> {
try {
boolean b = false;
System.out.println(false); // Escrevia b, mas b é sabidamente false.
if(carne.getText().endsWith("Carnê")){
carne.setText("Tabela");
System.out.println(false); // Escrevia b, mas b é sabidamente false.
b = true;
System.out.println(true); // Escrevia b, mas b é sabidamente true.
}else{
carne.setText("Carnê");
System.out.println(false); // Escrevia b, mas b é sabidamente false.
b = false; // Não faz nada, pois b já é false.
System.out.println(false); // Escrevia b, mas b é sabidamente false.
}
System.out.println(b);
Ligacao.setFlag(b);
System.out.println(b + "\n");
} catch (Exception e) {
e.printStackTrace();
}
});
Let’s simplify it then, apart from the System.out.println
unnecessary and unnecessary instructions:
carne.setOnAction((Carne) -> {
try {
boolean b = false;
if (carne.getText().endsWith("Carnê")) {
carne.setText("Tabela");
b = true;
} else {
carne.setText("Carnê");
}
Ligacao.setFlag(b);
System.out.println(b + "\n");
} catch (Exception e) {
e.printStackTrace();
}
});
We can simplify it a little bit more if we notice that b
will only be true if the condition of the if
is true and with this we can use it directly as the value of b
:
carne.setOnAction((Carne) -> {
try {
boolean b = carne.getText().endsWith("Carnê");
carne.setText(b ? "Tabela" : "Carnê");
Ligacao.setFlag(b);
System.out.println(b + "\n");
} catch (Exception e) {
e.printStackTrace();
}
});
Here, it is still necessary to question the name of the lambda parameter: Carne
. This is not an appropriate name, as this is a variable and therefore should start with lowercase letter. In addition, have two variables whose name differs only by upper and lower case, namely carne
and Carne
is a bad programming practice because it leaves the code very confusing. I suggest renaming the Carne
for something else.
Now, coming back to your first class, you realize that you’ve forgotten the private
in the declaration of the static field filtrar
, but let’s take a look at what method get
makes (already applied the corrections I suggested before):
private static FilteredList<Person> filtrar;
public static FilteredList<Person> get(ObservableList<Person> obs, ObservableList<Person> obs2) {
filtrar = new FilteredList<>(obs, p -> true);
if (b) {
filtrar.removeAll(obs);
filtrar = new FilteredList<>(obs2, p -> true);
}else{
filtrar.removeAll(obs2);
filtrar = new FilteredList<>(obs, p -> true);
}
return filtrar;
}
If b
is true here’s what happens:
- Create a list of all elements of
obs
and assigns it to the static variable filtra
, therefore missing the previous reference of the list no matter what it was.
- Removes all elements of
obs
which are in the list (and therefore all elements), which results in an empty list.
- Create another list of all elements of
obs2
. The previous list is lost to the garbage collector, and so the work done on it in steps 1 and 2 has been wasted.
- Returns the list with the elements that were in
obs2
.
If b
is false:
- Create a list of all elements of
obs
and assigns it to the static variable filtra
, therefore missing the previous reference of the list no matter what it was.
- Removes all elements of
obs2
which are on the list, which results in a list with the elements of obs
who are not in obs2
. If there is no element on both lists, it will do nothing.
- Create another list of all elements of
obs
. The previous list is lost to the garbage collector, and so the work done on it in steps 1 and 2 has been wasted.
- Returns the list with the elements that were in
obs
.
Note that in both cases, the list that is kept at the end is irrelevant, because the way the method get
has been coded, any attempt to access the contents of this list will necessarily cause it to be lost.
All this would be so much simpler:
public static FilteredList<Person> get(ObservableList<Person> obs, ObservableList<Person> obs2) {
return new FilteredList<>(b ? obs : obs2, p -> true);
}
And that’s how your code ends up:
class Ligacao {
private static boolean b;
public static void setFlag(boolean novoValor) {
b = novoValor;
}
public static FilteredList<Person> get(ObservableList<Person> obs, ObservableList<Person> obs2) {
return new FilteredList<>(b ? obs : obs2, p -> true);
}
}
carne.setOnAction(x -> {
try {
boolean b = carne.getText().endsWith("Carnê");
carne.setText(b ? "Tabela" : "Carnê");
Ligacao.setFlag(b);
System.out.println(b + "\n");
} catch (Exception e) {
e.printStackTrace();
}
});
FilteredList<Person> filtrar = Ligacao.get(obs(), obs2());
Finally, some people may find that accessing the static field using this
causes a build error. This is not true because it is allowed to access a static field using a variable instead of the class name and in this case the variable is the this
). However, this is bad programming practice and should never be done, but the language allows.
And also accessing a static variable from within the constructor is perfectly valid in the Java language. Most of the time (not always, there are some exceptions), doing this is not good programming practice and tends to leave the code bad and prone to occurrence of bugs, but the Java language allows.
A method is possible in JAVA Static use an attribute not Static? For that to be possible, I’m thinking C#, would be to declare
b
aspublic static boolean b;
– ramaral
That’s how I ended up erasing.
– lucas daniel
I believe that your code does not Compile. A constructor cannot access a static variable. Also, it is under the wrong name.
– EduardoFernandes
I’m sorry I put the code missing some parts, but the code compiles.
– lucas daniel
@Eduardofernandes There is no rule prohibiting a constructor from accessing a static variable. It is true that this is not a good practice of programming, but the compiler and the JVM accept this normally.
– Victor Stafusa
Haha truth, really allows :)
– EduardoFernandes
@ramaral the
this.b = b;
compiles yes, because it is allowed to access a static field using a variable instead of the class name (in this case, the variable is thethis
). However, this is bad programming practice and should never be done, but the language does allow.– Victor Stafusa
@Victorstafusa My comment did not refer to that. At the time the field
b
nay was declared static and was accessed in the static methodget
.– ramaral