I wonder if there's a simple way to to find all methods accessing a field directly. More precisely:
I'd like to assure that there's exactly one method writing a field and exactly one method reading it. All other accesses should use these two.
Background: When a field gets written, I need to record the fact somewhere I can do this easily using a generated setter, but I'd like to assure that I don't circumvent it somewhere.
It's for mobile rather than server, so I don't want / can't use interfaces or run-time bytecode rewriting...
I know, there's ASM, but AFAIK using it means more work that I'd like to spend. I hope, there's a better way.
I didn't think of it, but have to state that code changes are allowed, but memory is tight. So encapsulating fields (e.g., Java FX style) or making a backup is too bad. There are quite a few fields, so actually anything requiring to touch them all is not good.
I could imagine parsing the sources, which is either complicated or prone to false positives as the same identifier has different meanings depending on the context. It may be even shadowed (e.g., in a nested class declaring an equally-named variable), but then I'd gladly change the code to avoid the problem.
Getting a structured information from the class file would surely be better.
Encapsulation can be achieved by Declaring all the variables in the class as private and writing public methods in the class to set and get the values of variables. It is more defined with the setter and getter method.
We can create a fully encapsulated class in Java by making all the data members of the class private. Now we can use setter and getter methods to set and get the data in it. The Java Bean class is the example of a fully encapsulated class.
Encapsulation allows you to hide specific information and control access to the internal state of the object. If you're familiar with any object-oriented programming language, you probably know these methods as getter and setter methods.
Properties allow clients to access class state as if they were accessing member fields directly, while actually implementing that access through a class method. This is ideal. The client wants direct access to the state of the object and does not want to work with methods.
Encapsulation in Java is at the object or class level; the strictest access control modifier is private
, but even then, every method within the same class can access the private
fields. So, if you want to encapsulate behaviour of fields, this can be achieved by representing the fields as objects.
Here's a class representing a mutable field:
public class MyField<T> {
private T value;
MyField(T initialValue) {
value = initialValue;
}
public T get() {
return value;
}
public void set(T newValue) {
// any logging goes here
value = newValue;
}
}
Then if you want this logging behaviour to apply to a field name
, declare name
as type MyField<String>
instead of String
:
public class Person {
private final MyField<String> name;
private final MyField<Integer> age;
public Person(String name, int age) {
this.name = new MyField<>(name);
this.age = new MyField<>(age);
}
public String getName() {
return name.get();
}
public int getAge() {
return age.get();
}
public void setName(String name) {
this.name.set(name);
}
public void setAge(int age) {
this.age.set(age);
}
}
Advantages:
MyField.value
is private, it's easy to verify across all instances that its value is never set without the logging behaviour being triggered.get
and set
methods; there is no need for a separate verification stage.Disadvantages:
MyField
objects has some overhead in memory use.get
and set
will have some overhead in running time..get()
is not much, but it could harm readability in more complex expressions.I could imagine parsing the sources, which is either complicated or prone to false positives as the same identifier has different meanings depending on the context. It may be even shadowed (e.g., in a nested class declaring an equally-named variable), but then I'd gladly change the code to avoid the problem.
That's why modern IDEs exist -- they can analyze your code based on context instead of just grep
ping sources.
Take IntelliJ IDEA, for example:
Usages of field, method class, or other things are one shortcut away:
Not only in your project, but in dependencies and other linked projects as well!
This is also available in Eclipse-based IDEs and NetBeans, probably others too.
If you don't use any IDE, you can still use linters like Checkstyle. Just mark the field deprecated and ignore warnings in methods where you know usage is permitted, more about ignoring Checkstyle warnings in this answer: https://stackoverflow.com/a/1706844
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With