2

While studying the standard Java library and its classes, i couldn't help noticing that some of those classes have methods that, in my opinion, have next to no relevance to those classes' cause.

The methods i'm talking about are, for example, Integer#getInteger, which retrieves a value of some "system property", or System#arraycopy, whose purpose is well-defined by its name. Still, both of these methods seem kinda out of place, especially the first one, which for some reason binds working with system resources to a primitive type wrapper class.

From my current point of view, such method placement policy looks like a violation of a fundamental OOP design principle: that each class must be dedicated to solving its particular set of problems and not turn itself into a Swiss army knife. But since i don't think that Java designers are idiots, i assume that there's some logic behind a decision to place those methods right where they are. So i'd be grateful if someone could explain what that logic really is.

Thanks!

Update

A few people have hinted at the fact that Java does have its illogical things that are simply remnants of a turbulent past. I reformulate my question then: why is Java so unwilling to mark its architectural flaws as deprecated, since it's not like that the existing deprecated features are likely to be discontinued in any observable future, and making things deprecated really helps refraining from using them in newly created code?

Semisonic
  • 1,152
  • 8
  • 21
  • @amit, why not mark such methods as deprecated and offer a more elegant solution then? – Semisonic Mar 10 '15 at 08:26
  • "Why isn't this framework/language/etc. designed the way I think it should be?" questions are not usually on topic here because the people who made those design decisions are not here to answer you. – JLRishe Mar 10 '15 at 08:33
  • @JLRishe, I beg to differ. Java is not some bizarre tool with cryptic design principles behind it. It's a very popular platform, and anything that is so popular is simply bound to be clear and logical to the end-users. Since one is clearly entitled to understand why some functionality of a programming language is made deprecated, the same may be said about the functionality that seems to deserve the same fate, but for some reason doesn't have it. – Semisonic Mar 10 '15 at 08:38
  • I did not imply that Java was a bizarre tool or that it was not clear and logical (you are the one saying that some part of it is not logical). Your question can only be answered if (a) the people who made these design decisions come here to answer you or (b) those same people at some point publically announced their reasons for such design decisions and someone is able to dig that information up. (a) is very unlikely, and (b) is slightly less unlikely, but an unreasonable request for an SO question, so your question is off topic. FYI, "why was this deprecated" questions are generally OT also. – JLRishe Mar 10 '15 at 08:43
  • 2
    It actually has its little oddities, simply because it is dragging around a large amount of legacy. People desperately look for logic but its not there; mistakes were made and mistakes are there to stay. Removing the mistakes would mean software that relies on them being there will break. The next time someone asks themselves "why?", first open up the javadoc and see since when the thing you're confused about exists. If since before Java 1.4, better just move along. Its too old to ask why. – Gimby Mar 10 '15 at 08:52
  • @JLRishe, just one question: if you think that Java is clear and logical and i'm the one who doesn't see it, then why not simply share your wisdom with such backwards me =P? Plus, since people like Jon Skeet exist on SO, I do believe that the knowledge of why can still be obtained. – Semisonic Mar 10 '15 at 08:57
  • @Semisonic No matter how logical I may think Java is, as I have already explained twice, I _can't_ answer your question because I don't know the answer, and quite possibly only a small handful of people do. Was Jon Skeet on the Java design committee that added these features? – JLRishe Mar 10 '15 at 08:59
  • @JLRishe, while it's just my assumption, I am rather positive that he's personally acquainted with the Java designers, and since some of his posts here refer to the half-public sources like mailing lists, I still think that the answer to my question may be revealed, whether *you* personally have it or not. – Semisonic Mar 10 '15 at 09:09
  • @Semisonic Even if one SO member has some likelihood of knowing the answer to your question, that does not mean that your question is on topic. Questions about specific programming problems are on-topic. "Why did these people decide to do this?" questions are not. – JLRishe Mar 10 '15 at 09:20
  • @JLRishe, okay, assuming that you are correct, could you point me to a specific SO rule that would confirm your point? Not trying to say anything, but you're the only poster here who denies this question's relevance. – Semisonic Mar 10 '15 at 09:25
  • @JLRishe, and one more example. If your logic is true then the questions like "why do Java containers not support primitive types" are also off-topic, since it all boils down to the same "why did these people decide to do this". This way, half of SO would be closed because of "why? because f*** you, that's why" ;). – Semisonic Mar 10 '15 at 09:30
  • @Semisonic http://stackoverflow.com/help/on-topic _"a practical, answerable problem that is unique to software development"_ I would say the answerability of your question is questionable. _"If your logic is true then the questions like "why do Java containers not support primitive types" are also off-topic"_ "why do Java containers not support primitive types" has a specifc, clear answer: Primitive types don't inherit from Object and can't generally be used interchangeably with objects. – JLRishe Mar 10 '15 at 09:40
  • @Semisonic The follow-up question "Then, why don't primitive types inherit from Object?" would have a good likelihood of being off-topic, but even that has a fairly practical answer and is probably well documented. _"This way, half of SO would be closed because of "why? because f*** you, that's why""_ No, only the thankfully small contingent of "Why didn't they do this the way I think they should have?" questions would be closed. "How can I get this code to do what I want?" questions are perfectly on-topic, and those are what this site is intended for. – JLRishe Mar 10 '15 at 09:42
  • @JLRishe, _has a specifc, clear answer: Primitive types don't inherit from Object and can't generally be used interchangeably with objects_ - but _why_ are the containers designed to work with objects only? But okay, I get your point about this topic. It is as subjective and questionable as mine but you're fully entitled to have it. No point in arguing any further. – Semisonic Mar 10 '15 at 09:48
  • @JLRishe, I would think that SO is all about exchanging views and experience, helping people see something new that you already managed to comprehend. And while my question is not as practical as you would like it to be, it's still promoting understanding of a particular aspect of software development. That's my opinion. But thank you for sharing yours. – Semisonic Mar 10 '15 at 09:52
  • @Semisonic SO is not a forum. It's a Q&A site. A lot of the Q&As here can and should involve exchanging opinions and experience, but that cannot be their primary objective. If you go to http://stackoverflow.com/help/dont-ask you'll see a section about avoiding subjective questions. The boilerplate text for questions closed as "primarily opinion based" also says _"Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise."_ – JLRishe Mar 10 '15 at 10:03
  • 1
    insn't this a question for programmers.stackexchange.com ? btw the answer is always "legacy". – BigMike Mar 10 '15 at 10:06
  • @JLRishe, the last example is not relevant here. I did not ask for opinions, I asked for educated guesses at the very least. Also, as you can see, SO has such tags as language-design and library-design. What else could be marked with such tags if not the questions about why languages and libraries are designed as they are? – Semisonic Mar 10 '15 at 10:09
  • @BigMike, again, you're ignoring a part of the picture. If legacy is always the answer, then why some of it is marked deprecated and some of it isn't? – Semisonic Mar 10 '15 at 10:11
  • Lemme tell it in another way, Deprecation is a non solution. Just think what will happen if they remove java.util.Date... there are plenty of better alternatives, even within java, so why java.util.Date is still there ? What will happen if Oracle removes it ? Theory is good, but is just theory, real truth is often different. – BigMike Mar 10 '15 at 10:19
  • @BigMike, in an example I made in one of this topic's comments, some prominent Java books explicitly avoid covering deprecated features to clearly state that those should not be used in new code. Speculation about deprecation leading to removal is based on nothing since, like one of the posters said, there is probably no feature in Java that was removed due to deprecation, and the old Thread methods are still there. So, i don't see why deprecation is not a solution. Although I'm not sure whether posting a separate question about it on SO would be tolerated... – Semisonic Mar 10 '15 at 10:27
  • programmers.stackexchange.com is not SO. it's a different place, with different rules. in there questions like this are welcome, SO audience is more for practical matters. – BigMike Mar 10 '15 at 10:35

3 Answers3

4

This is a good thing to wonder about. I know about more recent features (such as generics, lambda's etc) there are several blogs and posts on mailing lists that explain the choices made by the library makers. These are very interesting to read.

In your case I expect the answer isn't too exiting. The reason they were made is hard to tell. But both classes exist since JDK1.0. In those days the quality of programming in general (and also Java and OO in particular) was perhaps lower (meaning there were fewer common practices, library makers had to invent many paradigms themselves). Also there were other constraints in those times, such as Object creation being expensive.

Many of those awkwardly designed methods and classes now have a better alternative. (See Date and the package java.time) The arraycopy you would expect to be added to the Arrays class, but unfortunately it is not there.

Ideally the original method would be deprecated for a while and then removed. Many libraries follow this strategy. Java however is very conservative about this and only deprecates things that really should not be used (such as Thread.stop(). I don't think a method has ever been removed in Java due to deprecation. This means it is fairly easy to upgrade your software to a newer version of Java, but it comes at the cost of leaving some clutter in the libraries.

The fact that java is so conservative about keeping the new JDK/JRE versions compatible with older source code and binaries is loved and hated. For your hobby project, or a small actively developed project upgrading to a new JVM that removes deprecated functions after a few years is not too difficult. But don't forget that many projects are not actively developed or the developers have a hard time making changes securely, for instance because they lack a proper regression test. In these projects changes in APIs cost a lot of time to comply to, and run the risk of introducing bugs.

Also libraries often try to support older versions of Java as well as newer version, they will have a problem doing so when methods have been deleted.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
Thirler
  • 20,239
  • 14
  • 63
  • 92
  • back in mid 90s quality of programming wasn't lower. Actually we may argue it was better since you had to make up everything on your own. My assembly days required more quality than modern java. – BigMike Mar 10 '15 at 08:42
  • `Arrays.copyOf` and `System.arraycopy` are doing different things. The first is for creating new arrays, the second for copying between existing ones. – SpaceTrucker Mar 10 '15 at 08:44
  • don't forget Arrays utility was added with 1.2 while System was the catch all utility since 1.0 – BigMike Mar 10 '15 at 08:47
  • Yes, I understand the Java's conservative nature. I do not, however, see why one should be so uptight about marking ugly vestiges of the language's past as deprecated. Indeed, such functionality may remain alive, but having it as deprecated would be a clear sign that it shouldn't be used in a modern code. For example, Herbert Schildt's "Java: The Complete Reference", which is a sort of official Java manual from Oracle, deliberately avoids covering the deprecated stuff as something that should not be used nowadays anyway. – Semisonic Mar 10 '15 at 08:48
  • @BigMike I have updated the answer to reflect this. The point I was trying to make is that there was not such a proper set of good practices for developing OO. Also as I indicated the Arrays class was added later. – Thirler Mar 10 '15 at 08:51
  • @SpaceTrucker Good point, I didn't notice, I will update the answer to reflect this – Thirler Mar 10 '15 at 08:52
  • @Thirler C++ was already out there, so OO best champion already was forcing us to think OO. Good practices were already in place, but we just never called 'em "patterns". Without a good mind set and good practices would have been hell living through million lines C projects written with the sole aid of VI. Back in the days we had no code completion, no IDEs and more important no StackOverflow, if we didn't had good patterns we would have been in a bad pinch. – BigMike Mar 10 '15 at 08:56
  • @Semisonic added a comment going further into why java chooses this deprecation policy. – Thirler Mar 10 '15 at 09:16
  • @Thirler, yes, thanks for your additional remark. But while you're explaining why it might be good not to remove something that's ugly but might still be in use, my question is more about deprecation as a warning to the newcomers: don't use this feature, it is there but it stinks. Because otherwise there will always be people who consider an existing non-deprecated functionality as an invitation to use it. There may even be a Murphy's law about it. – Semisonic Mar 10 '15 at 09:21
1

The Integer-example is probably just a design decision. If you want to implicitly interpret a property as Integer use java.lang.Integer. Otherwise you would have to provide a getter method for each java.lang-Type. Something like:

  • System.getPropertyAsBoolean(String)
  • System.getPropertyAsByte(String)
  • System.getPropertyAsInteger(String) ...

And for each data type, you'd require one additional method for the default: - System.getPropertyAsBoolean(String, boolean) - System.getPropertyAsByte(String, byte) ...

Since java.lang-Types already have some cast abilities (Integer.valueOf(String)), I am not too surprised to find a getProperty method here. Convenience in trade for breaking principles a tiny bit.

For the System.arraycopy, I guess it is an operation that depends on the operating system. You probably copy memory from one location to another in a very efficient way. If I would want to copy an array like that, I'd look for it in java.lang.System

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
Noordsestern
  • 98
  • 1
  • 8
  • `System.arrayCopy` may also be implemented to make use of the underlying hardware. – SpaceTrucker Mar 10 '15 at 08:53
  • @SpaceTrucker, it would then be an another sacrifice of usability in favor of underlying logic. Nothing forbids placing an array copy routine next to the other array routines but make it call some hadware-aware code, right? – Semisonic Mar 10 '15 at 09:14
0

"I assume that there's some logic behind a decision to place those methods right where they are."

While that is often true, I have found that when somethings off, this assumption is typically where you are mislead.

A language is in constant development, from the day someone proposes a new language to the day it is antiquated. In between those extremes are some phases that the language, go through. Especially if someone is spending money on it and wants people to use it, a very peculiar phase often occurs, just before or after the first release:

The "we need this to work yesterday" phase.

This is where stuff like this happens, you have an almost complete language, but the programmers need to do something to to show what the language can do, or a specific application needs a feature that was not designed into the language.

So where do we add this feature? - well, where it makes most sense to that particular programmer who's task it is to "make it work yesterday".

The logic may be that, this is where the function makes the most sense, since it doesn't belong anywhere else, and it doesn't deserve a class of its own. It could also be something like: so far, we have never done an array copy, without using system.. lets put arraycopy in there, and save everyone an extra include..

  • in the next generation of the language, people will not move the feature, since some experienced programmers will complain. So the feature may be duplicated, and found in a place where it makes more sense.

much later, it will be marked as deprecated, and deleted, if anyone cares to clean it up..

Henrik
  • 2,180
  • 16
  • 29