Const correctness in Java using Annotations? - java

Is there an existing library that allows me to annotate a Java method as #Const, so that the compiler (using apt I presume) will flag an error if it updates a field, or invokes a non-#Const method on a field; and annotate a parameter as #Const, so that the accepting method cannot invoke any of its non-#Const methods, or update any of its fields?
(Basically, trying to add const-correctness to Java using annotations; there are some obvious details not covered in the question above, such as assigning to/from a #Const-typed parameter, etc.)
I've found this: http://confluence.atlassian.com/pages/viewpage.action?pageId=182158080 but it seems like it's only available as part of IDEA.
Following a request for clarification below, here's sample code to show what I mean:
class Person {
private String name;
private String address;
#Const public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
... etc. for address
}
Now, if I define a method such as:
void processPerson(#Const Person p)
a line such as: p.getName() would be OK in processPerson, since getName was marked as a #Const method. But calling p.setName() from within processPerson would be flagged as an error.
Note that this is very different from final: if the parameter was defined as final Person p, any assignment to p would have been illegal, but it's still perfectly valid to modify what p refers to (either using p.setName(...) or even more directly, with p.name = ....

JSR-305 supposedly does just about what you're looking for
Personally, I'd see if I can use Hibernate Validator - Bean Validation (JSR-303) for that. It's a wonderful little lib (doesn't depend on hibernate, it's small) and it does wonders to keeping your data clean. See the documentation.
A google guy also started Contracts for Java recently, but it might not be production quality yet.

Take a look at the Checker Framework, which basically has checkers that try to detect software defects [JSR-305] via an extensible type annotation system [JSR-308].
It has an immutability checker (2 actually) which allows you to annotate code with immutability annotations like #Mutable, #Immutable, and #Readonly. This tool differentiates between an immutable instance and a read-only reference.
I love this framework and mainly use it for null checking, but I am trying to start using the immutability checker and interning checker more.
annotate a parameter as #Const, so that the accepting method cannot invoke any of its non-#Const methods, or update any of its fields?
Would look like:
void addFriend(#ReadOnly Friend friend) { this.friends.add(friend); }
allows me to annotate a Java method as #Const, so that the compiler (using apt I presume) will flag an error if it updates a field, or invokes a non-#Const method on a field; and
It would look like this for the example in the question:
public String getName(#ReadOnly Person this) {
return name;
}
The #ReadOnly here indicates the receiver (the this instance whose method is being called) should NOT be modified. Despite the apparent extra parameter, the method is still called as usual:
#ReadOnly Person person = new Person();
person.getName();

I am seconding #AlexR comment, this can be done using AspectJ, something along these lines:
public aspect ConstAspect{
declare warning : withincode(* *(..,#Const (*),.. ) ) : "Calling Const Method..";
}
This is not correct for your requirements, but I basically want to show an approach, In the above case any method which has a #Const on a parameter is tagged with a warning. With a better joinpoint, all the points of concern can be tagged with an error.

const was in C++. Java apparently ditched it on purpose. And now people growing up without really experienced const think it's a good idea.
Once you marked one method as const, it'll spread like cancer, pretty soon you'll find yourself const almost everything. It would have been better to have a not-const.
Utterly it's useless. It's only appealing academically, doesn't help anybody in real programmnig.

Related

How to run methods before and after Lombok #Setter

I want some of my methods to run before and after the Lombok #Setter.
For example:
#Setter(after="save")
private String name;
This should run method called "save" after the original setter has assigned a value to the field.
So after compilation it should look like this:
public void setName(String name){
this.name = name;
this.save();
}
Maybe there is something I could do with "onMethod" parameter? Sorry, I'm not professional in annotations.
There is currently indeed no way to do this; onMethod isn't going to help either (SOURCE/DISCLAIMER: I'm a core lombok dev).
We do have some plans to add such a thing, but before you go ahead and write a PullRequest to add such a feature, discuss it first. There are various ways to go here. The primary issue is syntax.
You can't put java code in an annotation (you can put it in a string but we veto such a move; your IDE is not going to help you, it's got the wrong syntax highlighting, and so on). You can't, unfortunately, put a method reference in an annotation either. You could put a string in there that mentions a method but we don't like that either (again, wrong colouring, no IDE autocomplete support).
That leaves magic naming (you make a method called afterName), but at that point lombok saves you nearly nothing, so why not just write the setter. A second option is to have a single 'validate' method that is called after any setter and is e.g. marked by an annotation. That's more the direction we're leaning into.
There's more to consider: Sometimes you'd want to mutate the incoming value before assigning it, and the same mutation should be done in case you have a builder, or have a constructor that accepts this param, as well. Thus, we have:
Post-set actions after any setter and construction, such as save().
Pre-"setting", validate and/or mutate, after any setter and construction. For example, let's say you have a setAge() method and you want to throw an exception if someone attempts to pass a negative value. The set shouldn't even happen, so a post-set handler can't do the job (it'd be too late, the object is already in an invalid state and you'd want to avoid this). Complication: Given that we want to do this pre-setting the field, how does this method get the values, then?
Hopefully that illustrates why this feature isn't (yet) in lombok and why it's a matter of a simple PR to add it.

Getting field name as string for already defined class. Is that possible?

Using byte-buddy is that possible to reference field name as string.
Here is what I m trying.
public class MyClass {
public int x;
public int y;
}
public String getMethodName() {
Class clazz = MyClass.class;
return clazz.getFields()[0].getName();
}
Here I will not get field x every time at position[0], so can not rely on that.
I have not used byte-buddy before.I searched questions present here related byte-buddy,also searched in documentation,but not found this particular type of example.
It is slightly unclear what you want, but my best guess is that you are referring to reflection.
Reflection gets its name from the idea that the code "looks at its reflection in a mirror", i.e. code looking at itself. The java reflection API is incredibly powerful, and allows you to do things possible impossible using other techniques, but it has major drawbacks.
For example:
public class MyClass {
public int x;
}
public String getMethodName() {
Class clazz = MyClass.class;
return clazz.getFields()[0];
}
public void setField(int newValue) {
Class clazz = MyClass.class;
clazz.getFields()[0].setInt(newValue);
}
The above code:
- defines a basic class
- provides a method to get the name of the first field
- provides a method to set the value of this field.
This seems to be what you are asking about.
However, there are serious downsides to using reflection.
It is very slow, up to 1000x slower, as the JVM is less able to make optimisations, since it has less information about the data it is working with at compile time.
It introduces the possibility for very nasty bugs. Once you open this can of worms, you can no longer confidently make assumptions about your code that you would before. If you have a class with a private variable with no setters, you might assume its value cannot be changed. Using reflection, it can.
It ignores Java's type checking system. This is one reason for the slowness mentioned above, since type checking must be done at runtime rather than compile-time. However, it also opens you up to type errors in a major way again, the entire thing Java's type system tries to save you from.
Because of this, reflection should only be used when there are literally no alternatives, for example, making a Json parsing library, writing an ORM system, etc. In other situtations, I have found that generally problems that seem to be reflection problems are actually abstraction problems.
Perhaps if, instead of getting a field by its String name, you could create an interface called ContainsMyField with a method called getMyField(), and any class that you expect to have this field should implement this interface. This option is much cleaner, faster, and safer.
It is not possible for Fields to get name as String of the field this way, using reflection.

Will it cause real issue if I use public field instead of getter/setter in Java? [duplicate]

This question already has answers here:
Are getters and setters poor design? Contradictory advice seen [duplicate]
(16 answers)
Closed 9 years ago.
I have been going through clean code book which states that the class should not expose the internal state of its data and only should be exposing the behavior. In case of a very simpl and dumb java bean exposing the internal state which getter's and setters, is it not worth just removing them and make the private members public? Or just treat the class as a data structure?
I don't think so. It depends of the lifetime of your Object and its "exposure" (external modification).
If you're only using it as a data structure, exposing fields in secure way (final) sounds enough:
public class Person {
public final String firstName;
public final String lastName;
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
The term POJO was intended to distinguish classes from JavaBeans or any other convention. As such a POJO is by definition NOT required to do anything.
I have been going through clean code book which states that the class should not expose the internal state of its data and only should be exposing the behavior.
This is called encapsulation and a good principle.
In case of a very simpl and dumb java bean exposing the internal state which getter's and setters, is it not worth just removing them and make the private members public?
That is an alternative approach. Some projects may forbid this approach while others may encourage it. Personally, I would favour this approach for classes which are encapsulated in some way already e.g. they are package local.
There is a view that some day in some way your class might have additional requirements and changing the "API" will be impossible. This goes against the YAGNI principle and very rarely proves to be the case and when it does has a much lower cost than adding lots of methods which don't do anything.
However, this is not always the case and if you don't use accessor methods you should consider what the impact will be on the project if you have to change it later. Using accessor methods every where means you never need to worry about this.
In summary, if you are pretty sure accessor methods are pointless and it won't be a problem to add them later, I would say you should use your judgement. However if you are not sure if it could be a problem in the future or you don't want to have to worry about it, use accessor methods.
The definition of POJO doesn't mandate getter/setter.
Experimentally, I am not using getter and setter in my current project.
The approach I am taking is this one:
unless necessary, don't provide getter/setter.
So far, I didn't find a case where I really needed get/set.
Some friend told me: "having get/set is helpful if in the future you need xyz"; my reply has been: when -in the future- I need to do so, I will provide the getter and setter; I don't want to anticipate anything.
The objection about incapsulation, that some may raise, is not really a valid one: providing getter and setter breaks incapsulation in the same manner, plus you have additional lines of (useless) code. Bugs may also lay in getter and setters.
This is an example of one of a non-trivial domain class:
public class SSHKey implements IsSerializable {
public Long id;
public Long userId;
public String type;
public String bits;
public String fingerprint;
public String comment;
#SuppressWarnings("unused")
private SSHKey() { // required by gwt-rpc
}
public SSHKey(String text) throws InvalidSSHKeyException {
Ensure.that(text != null, new InvalidSSHKeyException("Invalid Key"));
text = text.trim();
String[] parts = text.split(" ", 3);
Ensure.that(parts.length >= 2,
new InvalidSSHKeyException("Invalid Key"));
type = getType(parts);
Ensure.that(type.equals("ssh-rsa") || type.equals("ssh-dss"),
new InvalidSSHKeyException(
"Key must start with 'ssh-rsa' or 'ssh-dss'"));
bits = getBits(parts);
comment = getComment(parts);
}
private String getBits(String[] parts) {
return parts[1];
}
private String getComment(String[] parts) {
if (parts.length == 3)
return parts[2];
return type + " " + bits.substring(0, min(15, bits.length())) + "...";
}
private String getType(String[] parts) {
return parts[0];
}
}
The constructor takes the responsibility to validate and prepare the data to be manageable. Thus this logic doesn't need to be in a setter/getter.
If I was shown object with public members some years ago, I would probably not like them; maybe I am doing something wrong now, but I am experimenting and so far it is ok.
Also, you need to consider if your class is designed to be extended or not (so, foresee the future is part of the requirements), and if you want your object to be immutable. Those things you can only do with get/set.
If your object must be immutable, and you can avoid the empty constructor, you can just add 'final' to the member instances, btw.
Unfortunately I had to add IsSerializable (similar to java.io.Serializable) and an empty constructor since this is required by gwt. So, you could tell me then "you see? you need the getter an setter"; well not so sure.
There are some jdbc frameworks which promote the use of public fields btw, like http://iciql.com
This doesn't imply that this project is correct, but that some people are thinking about it.
I suppose that the need of getter/setter is mostly cultural.
The issue with making the members accessible is that you no longer control them from inside the class.
Let's say that you make Car.speed accessible. Now, everywhere in you program there can be some reference to it. Now, if you want to make sure that speed is never set a negative value (or to make the change synchronized because you need to make it thread safe), you have to either:
in all the points where speed is accessible, rewrite the program to add the control. And hope that everybody that changes the program in the future remembers to do so.
make the member private again, create the getter and setter methods, and rewrite the program to use them.
Better get used to write getter and setter from the beginning. Nowadays, most IDEs do it automatically for you, anyway.
The canonical answer to this is: You don't know whether your simple data structure will stay so simple in the future. It might evolve more than you expect now. It might be also possible, that anytime soon you want some "value changed" observer in that bean. With getter and setter methods you can do this very simply later without changing you existing codebase.
Another pro point for getter/setter is: If in Rome, do like the Romans... Which means in this case: Many generic frameworks expect getter/setter. If you don't want to rule all these usefulls frameworks out right from the start then do you and your colleagues a favour and simply implement standard getter/and setters.
Only if you expose a class in a library that's used beyond your control.
If you do release such a library, the Uniform Access Principle dictates that you should use getters and setters in order to be able to change the underlying implementation later without requiring clients to change their code. Java doesn't give you other mechanisms to do this.
If you use this class in your own system, there's no need: your IDE can easily encapsulate a public field and update all its usages in one safe step. In this case, brevity wins, and you lose nothing for the time where you need encapsulation.
I think it's a good idea to use getters and setters, unless you have very specific speed/memory/efficiency requirements or very simple objects.
A good example is a Point, where it is probably both nicer and more efficient to expose it's .x and .y variables.
That said, it will actually not be a big effort to change the visibility of a few member variables and introduce getters and setters even for a large codebase, if you suddenly require some logic in a setter.
JavaBeans require getters and setters. POJOs do not, anyway this has its benefits
The objetive of the getters and setters is to achieve encapsulation, which manages the internal state of object. This allows you to add or change business rules in your application after the application has been implemented only change the getter or setter code, example, if you have a text field that only allows for more than 3 characters can check before assigning it to an attribute and throw an exception, other reason for not doing this is if it's possible you'll want to change the implementation or change variable names or something like. This cannot be enforced if the field is publicly accessible and modifyable
anyway you can use your IDE to generate setters and getters.
If you are developing a simple application can be recommended, if your application is complex and must give maintenance is not recommend.
for the data-type objects, like POJO / PODS / JavaBean, at python you have only public members
you can set those and get those easily, without generating boilerplate setter and getter code(in java these boilerplate code usually(98%) exposes the inner private tag as noted in the question)
and at python in the case you would need to interact with a getter, then you just define extra code only for that purpose
clean and effective at the language level
at java they chose the IDE development instead of changing base java, see JavaBean e.g. how old that is and java 1.0.2 is how old...
JDK 1.0 (January 23, 1996)
The EJB specification was originally developed in 1997 by IBM and later adopted by Sun Microsystems (EJB 1.0 and 1.1) in 1999
so just live with it, use the setter getter because those are enforced by java surroundings
That's the true what #Peter Lawrey explains about encapsulation.
Only one note: it's more important, when you are working with complex objects (for example in the domain model in a ORM project), when you have attributes that aren't simple Java types. For example:
public class Father {
private List childs = new ArrayList();
public Father() {
// ...
}
private List getChilds() {
return this.childs;
}
public void setChilds(List newChilds) {
this.childs = newChilds;
}
}
public class Child {
private String name;
// ...
private String getName() {
return this.name;
}
public void setName(String newName) {
this.name = newName;
}
}
If you expose one attribute (like the childs attribute in the Father class) as a public, you won't be able to identify what part of your code are setting or changing one property of your exposed attribute (in the case, for example, adding new Child to a Father or even changing the name of a existing Child). In the example, only a Father object can retrieve the childs content and all the rest of the classes can change it, using its setter.

Do we need get/set method for enum? [duplicate]

I need a small Container-Class for storing some Strings which should be immutable. As String itself is an immutable type, I thought of something like that:
public final class Immu
{
public final String foo;
public final String bar;
public Immu(final String foo, final String bar)
{
this.foo = foo;
this.bar = bar;
}
}
Many people seem to object using public fields at all and use Getters instead. IMHO this would be just boilerplate in this case, because String itself is immutable.
Other thoughts I may be missing on this one?
I would do what you believe is simplest and clearest. If you have a data value class which is only used by a restricted number of classes. esp a package local class. then I would avoid getter/setters and use package local or public fields.
If you have a class which you expect other modules/developers to use, following a getter/setter model may be a safer approach in the long run.
The problem is the uniform access principle. You may later need to modify foo so that it's obtained through a method instead of being fixed, and if you exposed the field instead of a getter, you'll need to break your API.
This answer is obviated:
Why not
interface Immu { String getA() ; String getB ( ) }
Immu immu ( final String a , final String b )
{
/* validation of a and b */
return new Immu ( )
{
public String getA ( ) { return a ; }
public String getB ( ) { return b ; }
}
}
I found this thread hoping for some actual arguments, but the answers I've seen here didn't help me all that much. After some more research and thinking I think the following has to be considered:
public final looks cleanest for immutable types.
Mutable types could be altered by accessors even if this is not intended - in concurrent environments this could lead to a lot of headaches.
There can be no no-arguments constructor. This is importent if you need factory methods (e.g. for LMAX Disruptor). In a similar way instantiating your objects via reflection becomes more complicated.
Getters and setters can have side effects. Using public final clearly tells the programmer that no hidden magic is occuring and the object is inherently dumb :)
You can't return a wrapper or a derived class instance to the accessor. Then again, this is something you should know about when the field is assigned its value. In my opinion container classes should not be concerned about what to return to whom.
If you're mid development and no guideline is stopping you and the project is isolated or you have control over all involved projects I'd suggest using public final for immutable types. If you decide you need getters later on, Eclipse offers Refactor -> Encapsulate Field... which automatically creates these and adjusts all references to the field.
I use the public-final-field (anti?)pattern on home projects for classes which are basically an immutable data structure with a constructor, along with absolute basics like equals(), hashCode(), toString(), etc. if required. (I'm avoiding the word "struct" because of the various different language interpretations of it.)
I wouldn't bring this approach to someone else's codebase (work, public project, etc) because it would likely be inconsistent with other code, and principles like When In Rome or Least Surprise take priority.
That said, with regard to Daniel C. Sobral's and aioobe's answers, my attitude is that if the class design becomes a problem because of unforeseen developments, it's the work of 30 seconds in an IDE to privatise the fields and add accessors, and no more than 5 or 10 minutes to fix broken references unless there are hundreds of them. Anything that fails as a result gets the unit test it should have had in the first place.:-)
[Edit: Effective Java is quite firmly against the idea, while noting that it's "less harmful" on immutable fields.]
Forget about encapsulation, immutability, optimization and all other big words. If you are trying to write good java code, I would recommend you just use getter simply because it is java friendly, and most importantly it saves ton of time googling why.
For example, you probably would not expect using streams when you write the code, but later you found
listOfImmus.stream().map(immu -> imm.foo).collect(Collectors.toSet()); // with field
listOfImmus.stream().map(Immu::getFoo).collect(Collectors.toSet()); // with getter
Supplier<String> s = () -> immu.foo; // with field
Supplier<String> s = immu::foo; // with getter
// final fields are hard to mock if not impossible.
Mockito.when(immuMock.getFoo()).thenReturn("what ever");
//one day, your code is used in a java Beans which requires setter getter..
¯\_(ツ)_/¯
This list can be long or short or may be none of them makes any sense to your use case. But you have to spend time convincing yourself (or your code reviewers) why you can or should rebel against java orthodoxy.
It is better to just write the getter/setter and spent the time for something more useful: like complaining java
Since Java 16, you can use records.
public record Immu(String foo, String bar) {}
All of a record's attributes are automatically final and it automatically has methods like equals(…) and toString() and the constructor.
The getters of the attributes have the same name as the attributes, in this case, they are foo() and bar().
The methods can be overridden, more information is in the documentation.
It is not very clear if someone is going to use your code through an API.
You are also missing an opportunity to validate the input, if you are going to require some later.
Using public final may be fine for such small job, but it cannot be adapted as a standard practice,
Consider the situation below.
Public class Portfolio {
public final String[] stocks;
}
Of course, being immutable, this object is initialized vis constructor, and then accessed directly. Do I have to tell you the problem in it? It’s evident!
Consider your client writing the code like below -
Portfolio portfolio = PortfolioManager.get(“Anand”);
Portfolio.stocks[0] = “FB”;
portfolio.calculate();
Is this doable? Your client libraries are able to manipulate the state of your objects, or rather able to hack within your runtime representation. This is a huge security risk, and of course tools like SONAR catch it upfront. But its manageable only if you are using getter-setters.
If you are using getters, you can very well write
Public class Portfolio {
private final String[] stocks;
public String[] getStocks() {
return Arrays.coptOf(this.stocks);
}
}
This prevents you from potential security threat.
Looking at the above example, using public final is strongly discouraged if you are using arrays. In such case, it cannot become a standard. A person like me, will refrain from using a code practice that cannot become a uniform standard across all data types. What about you?

Detect changing value of object passed as parameter

I'm now working with code that looks like this
public String getName(User user) {
user.setSth(...);
return user.getName();
}
I think it's bad practice to change objects passed as parameters. Is there a tool that detects that kind of code? I looked at findbugs, pmd and checkstyle, but could not find any check for this.
P.S. sorry for bad example.
I think you are already on the right track: your best tool to detect this sort of code is almost certainly Findbugs. However, you will probably need to write your own detector for this pattern. Here is an example of how you would write a detector, though it isn't exactly the detector that you're looking for.
Caveat: I don't really agree that a side-effecting getter is always bad style. However, if you really want to find that sort of thing, I would recommend Findbugs.
You won't find anything because, from a tool's point of view, "getName" and "setSth" are just method calls. Humans say "this is a getter" and "this is a setter" but tools don't. In fact, getName() is not a getter because getters don't accept arguments.
So the tool can't see anything unusual because methods change objects all the time.
If you want to enforce this rule, have a look at extending findbugs and PMD. Both allow you to define additional constraints. What you're looking for is probably:
If method name starts with "get"
AND method body calls method of any object passes as parameter
then print a warning. That shouldn't take too long. Run this and you will see how many "false positives" you get (warnings about methods which are actually OK). This will help you determine whether it's worth to pursue this further. Plus you'll have a new item to add to your CV :)
You could make User immutable (declare it final, declare all properties final and remote the setters. I know that isn't practible everywhere but in many places that is good and you will have no problems in passing that to other functions).
If you have to "change" something, you can implement functions like newId in that sample:
public final class User {
private final String name;
private final int id;
User(String name, int id) {
this.name = name;
this.id = id;
}
public User newId(int newId) {
return new User(this.name, newId);
}
//getters here;
}
The built in String, Integer, ... classes do that, too.
You can create an interface called UserView containing only "getters", make User implement it and use the new UserView interface as the type of parameter.
interface UserView{
public String getName();
...
class User implements UserView...
public String getName(UserView user) {
user.setSth(...); // Will not compile
return user.getName();
}
Actually this is something that in C++ was very easy to do via the const qualifier. You would define a parameter as const and for that parameter you could only call methods defined as const - usually, getters.
In Java this is absent and frankly, I don't really mind. As mentioned there are source code analyzers which can check this behavior, as well as meta-programming methods to do this as well.
Personally, I believe that if the method is named properly, there is no problem of passing an object to it so that is it modified.
There are tools that can "reason" about code on a higher level than compilers typically do. Declarative Metaprogramming for example is a discipline that allows writing programs to check if another program conforms to a certain design, or, conversely, to mine for code smells and anti-patterns.
Some links:
http://prog.vub.ac.be/DMP/
http://www.cs.bris.ac.uk/Publications/pub_master.jsp?id=1000273
and for the rest
http://www.google.com/search?num=100&hl=en&q=Declarative+Metaprogramming
You're looking for something like "const" in C++ that will enforce making the parameter value as immutable as the reference that's passed in. Immutable objects guarantee that, if you can live with them.
You're arguing that this is "bad" because side effects like this can surprise a user. That's valid, but it's only harmful if it's an unwanted surprise.

Categories

Resources