-5

Please refer below example.

==== before ====

---- A.java ---

var userAccounts = userService.getUserAccounts();

--- B.java

class UserService {
public OldUserAccounts getUserAccounts();
}

==== after ====

---- A.java ---

var userAccounts = userService.getUserAccounts();

--- B.java

class UserService {
public NewUserAccounts getUserAccounts();
}

There is no change in the B.java source file although A.java changed. the B.class file's information has the 'userAccounts' variable type is 'OldUserAccounts' Aren't you? if i apply modified source files to the real server. 'var' will spawn a bug ?

Note : I know its a bad practice, even without var changes can be bytecode-incompatible. the idea of rebuilding the entire project is not good in my case. cost is too much

Any ides or workarounds ??

Akila
  • 1,258
  • 2
  • 16
  • 25
  • 4
    actually, the change seems to be in B.java – Stultuske Mar 29 '18 at 06:30
  • 8
    *Most programmers will only apply modified source files to the real server*: no. No one sane does that. Sane developers use their build tool to compile, assemble and test their code. The produced artifact (a jar file or a war file, often acompanied with several other files (config, etc.)) are then uploaded and replace the previous install. Source files are not needed on the server. – JB Nizet Mar 29 '18 at 06:34
  • 5
    *"the idea of rebuilding the entire project is not good in my case. cost is too much"* How can the "cost" be too much? How long does a full build take? If your project is so large that build takes more than a few minutes, then you should be doing daily builds on a build server. Heck, you should probably be doing that anyway, regardless of build time. And a really large project should be split into modules *(not necessarily Java 9 modules)*. Your build is **automated**, right? – Andreas Mar 29 '18 at 06:54
  • 2
    If you have any problems with `var` in a very specific case, there *is* a workaround. Declare the type in that case. – Stefan Steinegger Mar 29 '18 at 07:01
  • 3
    This has nothing to do with `var`. If you'd written `A` with a manifest type (`OldUserAccounts u = service.getUserAccounts()`), it would break in exactly the same way. The problem is you made a binary-incompatible change. – Brian Goetz Mar 29 '18 at 13:36

1 Answers1

8

There is no change in the B.java source file although A.java changed.

You mean there's no change in A.java even though B.java changed.

Yes, if you change B.java, you must recompile A.java, which depends on it. var doesn't change anything in this regard, you needed to do that anyway. The only difference is that the source code in A.java doesn't change if you use var, and does if you don't. It needs recompiling regardless.

Most programmers will only apply modified source files to the real server.

Citation needed.

Most programmers on non-toy projects use a proper build tool. Using a proper build tool will ensure you recompile and redeploy as necessary. If you're picking-and-choosing what you recompile and redeploy, and not always recompiling classes when their dependencies change, you will indeed have a problem as of Java 10 — and you already have a problem in Java 9 and earlier. You will make an incompatible change to B.java, fail to recognize you need to modify and rebuild A.java, and hit a runtime incompatibility.

var isn't the problem in the scenario you describe. The project tooling is.

But var is entirely optional. If you think it will cause trouble on your project, don't use it.

Roman Pokrovskij
  • 9,449
  • 21
  • 87
  • 142
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 2
    Fun fact: the type of local variables is mostly irrelevant to the execution, so it is indeed irrelevant whether `var` has been used or not. It’s already the invocation instruction pointing to `OldUserAccounts getUserAccounts()` in `UserService` that breaks when the return type changes. – Holger Mar 29 '18 at 11:50