Generics in legacy code

2019-06-16 04:03发布

问题:

We've got a fairly large amount of code that just made the jump to Java 5. We've been using generics in those components targeted at being released in the Java 5 version, but the remaining code is, of course, full of raw types. I've set the compiler to generate an error for raw types and started manually clearing them, but at the present rate it'll take a very long time to go through with it (there are about 2500 errors). And that's with Eclipse's helpful Infer Generic Type quick fix, which always gets rid of the errors, but often generates code that needs further work.

Is there any better way to dealing with this? Are there any automated tools better than Eclipse? Any way to apply the refactoring to all occurences instead of doing them one-by-one? Or do you just ignore the warnings?

回答1:

I would suggest ignoring the warnings. Otherwise, you'll be putting a lot of time into updating the legacy code without making any improvements to its functionality.

Update: Great comment from Luke that I thought should get more visibility: "Generics are a way to catch run time bugs at compile time. Unless this legacy code has bugs in it that you think are related to casting I would leave it alone (if it ain't broke, don't fix it)"



回答2:

As far as I know, you're going about it as efficiently as possible. It's obviously not perfect, but you'll finish eventually.

I recommend that you do it in stages, however; there are likely parts of the code that would benefit more from this than others, focus on those. Trying to do it all in one sweep runs the risk of introducing new bugs to your code. We have one such place where we have a collection that holds context-dependent data, and generics actually can't work for it.

Basically, do what you're doing, but do it in stages as part of other work, instead of trying to fix it all in one throw.



回答3:

Faced with a similar challenge, we opted to upgrade to Java 5 style generics only in the code that was edited for another reason. So if you have a bug to fix in DoItFast.java, update DoItFast.java to use Java 5 style generics. The areas of the code that are being edited and changed regularly will get updated quickly. After a few weeks or months of this behavior, you can reevaluate the condition of your code base.

If that doesn't get the job done fast enough for you, sometimes I'll use the slow time after lunch to just mindlessly cleanup a few classes and speed the process along.



回答4:

I don't think it is necessary to update all the old code. Maybe if you could somehow identify which parts of the old code are used frequently, and only update those to use generic types? Or maybe you could only worry when the raw type is returned from a public function? A lot of these cases are probably just private/local variables, which are already written without generic types and presumably work just fine, so it's probably not worth the effort to rewrite them.



回答5:

I understand with IDEA you can select all your classes, popup the context menu and select Refactor | Generify. Job done. It's certainly a more enjoyable experience to work with generified code (IMO).