-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Assumption: Add assertAllNotNull(Object... objects) #7730
Comments
How about we use For instance, this.googleId = Preconditions.checkNotNull(googleId);
this.name = Preconditions.checkNotNull(name);
this.isInstructor = Preconditions.checkNotNull(isInstructor);
this.email = Preconditions.checkNotNull(email);
this.institute = Preconditions.checkNotNull(institute); See: https://github.com/google/guava/wiki/PreconditionsExplained Not to mention we can do See
Furthermore,
I think this happened because we tried to reinvent the wheel, and did not consider the enormous work others have put into addressing the The other thing to notice is that See
Here’s the excerpt from Effective Java
And a longer discussion on Guava’s issue tracker, google/guava#1648. From
Also introduced in Java 7,
which also throws a https://docs.oracle.com/javase/7/docs/api/java/util/Objects.html#requireNonNull(T) And here's Guava's take on assertions
Then another problem would be excessive null checks, I think it's probably better to let things fail if a @Zhiyuan-Amos, what do you think? |
Generally, I think it's good that we standardise things to fail fast. This means that there will be a lot of null checks over the entire codebase, but it ensures that the scenario you mentioned above The debatable one would actually be in cases of overloaded methods: public void foo(String bar) { // should we do assertNotNull(bar) here? foo(bar, "faz"); } public void foo(String bar, String faz) { assertNotNull(bar); assertNotNull(faz); // do something } The check at this point in time isn't necessary since null check for
That way, the developer may forget to do the precondition check. (I think we generally forget do precondition checks, myself included :P) Also, between using I think it doesn't matter whether IAE or NPE are thrown, since they aren't meant to be handled right? (At least for SE-EDU). |
@LiHaoTan we discussed more f2f, and we even discussed where should we put assertions (whether they should be in the entire code base, or only in components such as I think that should not be the focus of this issue. As you have pointed out, this issue can simply be about removing Perhaps the next thing to decide on is whether we should implement our own For example:
Over here we can't do what you suggested earlier:
because we are not assigning the attributes, rather we are passing it into a constructor. As such, calling something like: The con, however, is that we can't tell immediately which variable is null. |
I agree with you that it is probably not so important that we can tell immediately which variable is null. I also think that it is fine not to be able to pass error messages into However, I would think that there needs to be a stronger reason than just reducing the number of lines to add Guava also mentions
I'm not saying that we should take Guava as the canonical source though but we probably should consider more if we should add So going back to the public void createAccount(String googleId, String name, String email, String
institute, StudentProfileAttributes studentProfileParam) throws InvalidParametersException {
Assumption.assertNotNull(googleId);
Assumption.assertNotNull(name);
Assumption.assertNotNull(email);
Assumption.assertNotNull(institute);
Assumption.assertNotNull(studentProfileParam);
AccountAttributes accountToAdd = new AccountAttributes(googleId, name, email,
institute, studentProfile);
AccountPerformanceIndexes accountPerformanceIndexes = new AccountAttributes(googleId,
name, email, institute, studentProfile);
accountsLogic.createAccount(accountToAdd, accountPerformanceIndexes);
} In this case, we would have to assume the two constructors are perhaps package-private so they don't check for nulls themselves and in order not to repeat code we do the null check here. However, we could have simply had something as follows: AccountAttributes accountToAdd = new AccountAttributes(checkNotNull(googleId), checkNotNull(name), checkNotNull(email), checkNotNull(institute), checkNotNull(studentProfile));
AccountPerformanceIndexes accountPerformanceIndexes = new AccountAttributes(checkNotNull(googleId), checkNotNull(name), checkNotNull(email), checkNotNull(institute), checkNotNull(studentProfile)); Though that is repeating code so maybe we are just better off checkNotNull(googleId);
checkNotNull(name);
checkNotNull(email);
checkNotNull(institute);
checkNotNull(studentProfileParam);
AccountAttributes accountToAdd = new AccountAttributes(googleId, name, email,
institute, studentProfile);
AccountPerformanceIndexes accountPerformanceIndexes = new AccountAttributes(googleId,
name, email, institute, studentProfile); So perhaps one compelling reason for adding Though another issue is that should we just migrate all precondition checks to use Because take for example We should probably use an assert instead isn't it? Anyway, the method should have been private, not package-private. void calculatePercentageFrequencyAndAverage() {
Assumption.assertNotNull("Response Frequency should be initialised and calculated first.", responseFrequency); Also, the other thing is I don't know when assertions were illegal in App Engine, probably a long time ago and we should be migrating them to proper assertions instead. |
With regards to For example, when we see However, we would not be able to tell when one specifically passes |
@LiHaoTan you think we should switch to Guava? |
Quote from Guava:
This I agree. I'm wondering whether we can have a workaround. That is, whenever we encounter NPE, we log it down first before throwing NPE. That way, we can effectively find out which object caused the error (just have a counter to count which item in the varargs that it's checking). That way we need our own implementation of
Yup, sorry that I didn't specify myself clearer. We should only migrate precondition checks for public methods to use Guava, and private methods to remain using assertions.
Yup this I definitely agree. In Guava there's @damithc
However, Paul's comment isn't applicable for Teammates :) |
@damithc yes I think we should use Guava since we have already included it but we are not making much use of it.
Yea this can be a possible approach. As per we discussed this will require additional maintenance, e.g. writing tests for such a method so since scenarios such as the two constructor scenario are currently rare in the code, the cost required to create such a method may not be worthwhile. Maybe we can add it if we do find a compelling reason to add such a method in the future.
So for this issue, shall we focus on what you recommend here? :) |
Closing as explained in #7996. |
Assumption
has a methodassertNotNull(Object)
.This method has to be called multiple times if the caller has multiple objects that should not be null. This leads to unnecessary code verbosity.
For example, in
Logic#createAccount(String, String, boolean, String, String, StudentProfileAttributes)
, there are 5 calls ofassertNotNull(Object)
.Let's create a helper method
assertAllNotNull(Object... objects)
to resolve the issue of unnecessary code verbosity.The text was updated successfully, but these errors were encountered: