Discussions

News: Generics make code easier to maintain, or not?

  1. Generics make code easier to maintain, or not? (46 messages)

    In his latest Java Specialists' Newsletter, Heinz was demonstrating some simple code that automatically re-reads changed config files and notified property change listeners. The code used generics, and the question was posed in a follow-up newsletter: Do generics make Java code easier to maintain, or not? Heinz asked his 8000 subscribers, and 80% of the respondents said YES.

    I would like to invite you to read Issue095 - Self-reloading XML Property Files and then look at the follow-up.

    Please think about the issues carefully before responding. I have personally not made up my mind yet, because I do not feel that I have enough real-life experience with generics yet. In addition, even though I heard some good arguments in favour of generics, there are also strong voices against them.

    This is not a trick question, and not for marks, I am looking for brilliant insights from the 400'000 readers, not a mud fight :-)

    Threaded Messages (46)

  2. Generics promote durability[ Go to top ]

    On small projects generics will not help and may indeed hinder. When the team is small and focused and everyone understand the API there is little need (as the article mentions you rarely see a ClassCastException in the wild).

    However, as the team/project grows and may become segmented then generics are your friend. This is especially true if you have one part of a team putting together an API for server side functionality and another part of the team who has to interact with this API in order to perform some task. The use of generics in this case aids in communcation about what the API expects or returns. It also reduces the need for very detailed @param javadocs. This all makes the code more self documenting and durable.
  3. Generics are destroying Java[ Go to top ]

    They are completely unreadable... They provide no value and are only syntax sugar, it might seem sweet but it rots your code! I don't recall a single instance of class cast exception in production, and I hardly recall any instances of this exception in development. Its a VERY complicated PATCH over a none issue that was brought into the language simply for marketing purposes. I would personally tar and feather Joshua Bloch and once people start using this and run into the mess of maintaining generics I'm sure others would agree.
  4. Generics are destroying Java[ Go to top ]

    They are completely unreadable... They provide no value and are only syntax sugar, it might seem sweet but it rots your code! I don't recall a single instance of class cast exception in production, and I hardly recall any instances of this exception in development. Its a VERY complicated PATCH over a none issue that was brought into the language simply for marketing purposes. I would personally tar and feather Joshua Bloch and once people start using this and run into the mess of maintaining generics I'm sure others would agree.
    Now I would not go so far and tar and feather Josua Bloch but I would go so far and put the following sentence into the coding guidelines:

    <em>Thy must not use generics</em>

    With java we had the good things of typesafe object oriented programming without the bad things,like multiple inheritance, pointer mangling, operator overloading and templates. What shocks me most it that there is a new syntax construct and everyone I see talks about how this will benefit collections, a small, perfectly easy and usable API. If you are too damn stupid or lazy to use a typecast then you can always build typesafe collections without much of an effort. Templates were ok in C++ because there was no real type safety and they were used to wrap volatile collection implemenation that usually did low level stuff with pointers. Speaking of which: I do think we really need some pointers in Java. No, really, if this is what we get with typesafety, maybe it is time to dig out the good old smalltalk again or python.....
  5. Generics are destroying Java[ Go to top ]

     Speaking of which: I do think we really need some pointers in Java.
    We already have them, you know... (ever heard of NullPointerException?)

    What we don't have is pointer arithmetics. Care to give an example where this feature would be really useful?

    --
    Cedric
    http://beust.com/weblog
  6. Generics are destroying Java[ Go to top ]

    They are completely unreadable... They provide no value and are only syntax sugar, it might seem sweet but it rots your code! I don't recall a single instance of class cast exception in production, and I hardly recall any instances of this exception in development. Its a VERY complicated PATCH over a none issue that was brought into the language simply for marketing purposes. I would personally tar and feather Joshua Bloch and once people start using this and run into the mess of maintaining generics I'm sure others would agree.
    Hi Shai,

    what complications have you experienced in real life projects with generics? I am looking for arguments of where generics worked / did not work in real programming scenarios. I know that I am asking this question a bit earlier than is reasonable, since JDK 1.5.0 was just released a few days ago.

    Heinz
  7. Generics are destroying Java[ Go to top ]

    Hi Shai,what complications have you experienced in real life projects with generics? I am looking for arguments of where generics worked / did not work in real programming scenarios. I know that I am asking this question a bit earlier than is reasonable, since JDK 1.5.0 was just released a few days ago.Heinz
    Hi Heinz,
    I obviously don't use generics, I do however use JDK 1.5. I have been against generics since their inception because I already know the outcome.

    There are NO large scale projects using generics! In order to make a true large scale application you need multiple libraries and tiers, and at least some of them need to make use of generics. Currently most libraries and platforms haven't migrated to 1.5 and thus there is no real example. The problem is that by now its too late, we can't see the problems right now but we can't avoid them. I won't use generics but I will be forced because libraries (including the API) make use of them and thus force my hand.

    Even now when compiling applications I get warnings... Warnings are a piece of c##p! What's a warning? It has no meaning, every C application is littred with multiple warnings and they are (for the most part) ignored. In Java you hardly every rebuild all the classes and the warnings won't be apparent and they won't be relevant for those of us that don't use generics. Java has made the exact same mistakes C++ has made:

    1. The compiler tries to do to much and to make decisions for us.
    2. Syntax was deemed ugly (casting) so it was hidden with another syntax.
    3. Backward compatability was overrated - due to the ability to downcast generics they lose any bit of power they might have held and become very dangerouse to the avarge developer.

    I think we will all have excellent stories of stupid generics related bugs within the next couple of years. I'm trying to imagine a good story on how generics "solved" a problem and I can't imagin something like that.

    As bad as generics are, autoboxing is even worse and don't get me started on enums which are a pet peeve.
  8. Re: Generics are destroying Java[ Go to top ]

    Agreed. Instead they should have implemented C++ for the JVM.
    The advantage Java has over C++ is clarity, simplicity and relative cleanliness. This advantage eroding.

    Smalltalk had no static type checking and it is still the best OO language. Smalltalkers always laughed at C++ templates. Some argue that OO cannot be done with static typing (loss of dinamism, too much overhead). I like some advantages of static typing. But adding this hack to Java served little purpose, too much complexity for too little benefit. I'm just waiting to get STL hell in Java... soon code will be as unreadable as C++ and it will no longer be an OO language but a generic language for many people.

    But this is a moot argument now.. the cat is out of the bag.
  9. One of the things I liked in C++ was typedef which allowed me to redefine complex template definitions into ones that are easier to read all in one line, but you can do the same thing with Java albeit its in more than one line.

    For example your code Set<Map.Entry<String, Object>> may be replaced with PropertySet if you had.

    /**
     * typedef of Set<Map.Entry<String, Object>>
     */
    public class PropertySet extends Set<Map.Entry<String, Object>> {
    }

    I think this is better since its prevents clients of your class library from understanding the internals of your class libraries.

    Dealing with core Java classes are "low level" and you have to do a lot of <>s in order to get your code working. Its not a fault of the JDK though, those things should be that way otherwise things would be too restrictive. However, you should still hide those from those who are using your classes.
  10. That's a good tip.
  11. One of the things I liked in C++ was typedef which allowed me to redefine complex template definitions into ones that are easier to read all in one line, but you can do the same thing with Java albeit its in more than one line.
    Right, just create a new class for this. I posted a few thoughts on this technique here.

    --
    Cedric
    http://beust.com/weblog
  12. One of the things I liked in C++ was typedef which allowed me to redefine complex template definitions into ones that are easier to read all in one line, but you can do the same thing with Java albeit its in more than one line.For example your code Set<Map.Entry<String, Object>> may be replaced with PropertySet if you had.

    /** * typedef of Set<Map.Entry<String, Object>> */
    public class PropertySet extends Set<Map.Entry<String, Object>>
    {
    }
    BTW, you can create special class like EasyName and import it using static import feature, so haven't have to use EasyName.PropertySet

    /** * typedefs */
    piblic class EasyName {

        public static class PropertySet extends Set<Map.Entry<String, Object>> {}
        public static class UserMap extends HashMap<Map.Entry<String, UserObject>>{}

    }
  13. Explaination needed[ Go to top ]

    Why in java 5 Properties class is defined as follows:
    extends java.util.Hashtable<Object,Object>
    and not
    extends java.util.Hashtable<String,String>

    Second question why usage of Properties class instance as a parameter to InitialContext doesn't work anymore..
    Am I missing sth? I thought Properties are Hashtable and Hashtable is what we need as a constructor parameter. Help!! :)
  14. Generics and Properties[ Go to top ]

    Why in java 5 Properties class is defined as follows:
    extends java.util.Hashtable<Object,Object>
    and not
    extends java.util.Hashtable<String,String>
    This is a great example of where the lack of parametric polymorphism has caused problems in Java libraries. Properties was never intended to be a Hashtable<Object,Object>, but because there was nothing in the API that prevented it from being used as a Hashtable<Object,Object>, people just started using it that way - even parts of the JDK class library. Now, we're stuck with a Properties definition which must be Hashtable<Object,Object> for backwards compatibility reasons.

    God bless,
    -Toby Reyelts
  15. /** * typedef of Set<Map.Entry<String, Object>>  */
      public class PropertySet extends Set<Map.Entry<String, Object>> {}
    A nice idea, but doesn't get you all the way there to typedef. You have to define all the constructors too, otherwise you're limited to the implicit no-arg constructor.

    Another potential problem with this is the lack of equivalence. In order to be able to use this form of pseudo-typedef, all classes in an application must use the _same_ definition of PropertySet (not just equivalent definitions), otherwise different PropertySet instances may have different classes and will not be assignable to each other. Not so much of a problem in a self-contained application, but a big problem in a library. Remember the old C days, where every package defined symbols for TRUE, FALSE, int32, and the like? Remember what a pain it was to use two or three of these packages in a single application?

    Bottom line -- this trick could cause as many problems as it solves.
  16. Heinz asked his 8000 subscribers, and 80% of the respondents said YES.
    This is like asking "does your car make a pleasant noise?" While this is a question you _can_ ask, it is not a very important one.

    The important question about generics is: "does generics improve type safety enough to warrant the added complexity?"

    The answer to this question is more difficult to answer (and depends on the implementation; whether it is F-bounded or not, etc.)

    IMHO, generics is a great tool for improving type-safety, but increased maintainability, I think, is just a bonus (in some cases.)
  17. Semantics of J2SE 5.0 generics are more intricate than I initially surmised.
    If you have a strong background in C++ templates, there are some painful "gotchas" lurking in the shadows for you.
    Here is a good read on J2SE 5.0 generics.
    The important question about generics is: "does generics improve type safety enough to warrant the added complexity?"
    There was a lot of thought put into making "generified" libraries in the JDK backwards compatible with legacy Java code (kudos to Sun & company). This way, if you don't think generics are worth it, you can still continue writing pre-J2SE 5 Java code.
  18. C++ Templates and Gotchas[ Go to top ]

    If you have a strong background in C++ templates, there are some painful "gotchas" lurking in the shadows for you
    and if you do not have a strong background in C++ - are there any painful gotchas?
  19. IMO generics will make code much more self-documenting. Ive lost count of the number of times Ive had to read implementation code to discover what type of objects are going to be returned by an API method with a continer return type. Somtimes Ive even had to resort to writing a test app to make the call and then introspect the container elements - this total crap. Now whenever I come accross a container reference I can just browse to the declaration and know exactly what s going to be in there.
    That's exactly what you can do in Pascal, but that's something Object Oriented languages do better, because of polymorphism achieved by inheritance.

    If you need to know exactly what's inside your container it is simpler to extend the container and do the cast there.
  20. The important question about generics is: "does generics improve type safety enough to warrant the added complexity?"
    That is exactly the question. Its easy to see that generics are useful - but enough to justify their complexity?
    It is early days yet... but my gut feeling is that for most problems, they wont be. But that wont stop them being used...

    I have to say that templates are not something that I have missed in Java...
    And I do believe that they have a significant impact on complexity.
    Not least the legibility.

    Given that I have (and do) spent a bit of time teaching Java to people migrating from C, C++ or VB, the thing that has always made this job easy has been the simplicity of Java.

    How do I explain templates to someone with little OO language experience?

    They have enough on their plate getting their head around interfaces, inheritance and polymorphism... now we throw templates into the mix...

    Is it the end of the simplicty of Java?

    -Nick
  21. Generics makes life easier while mapping Java Objects to XML types. Currently there is no easy way to convert Map or List directly to XML Objects because of unknow type definition.

    Generics will allow JAXB / Castor / XMLBean ... to give an implementation to directly convert Map's or List's to user defined XML types.

    -Kirupa
  22. Heinz asked his 8000 subscribers, and 80% of the respondents said YES.
    How many of those 80% used generics? I'm sure some of them ran this cool TestGen.java class they wrote in two minutes with plain vanilla generics and autoboxing... This is simple, everything is simple when it works!

    The problem is that generics DON'T work!

    Ask 100 Java developers about the syntax described by Heinz <? extends T> and I'll bet that 99 of them won't have a clue.

    Let people use generics for a year or two and the results will be completely different.

    Generics bring nothing to the table, they are a different syntax for a type cast with many additional hidden complexities. The problem is that as the syntax is getting wider the pitfalls are getting deeper, when people will run in to class cast exceptions in generic code (it can happen) they would be stuck and assume the JVM has a bug...

    About the typedef idea: its one of the things I despise the most about C++. When looking at Java code you could easily tell what would happen:

    z = a + b;

    This is simple a, b and z are either numbers or Strings, not that many options. In C++ you can define b to map to a function call and overload the +/= operators creating something completely different.

    By using typedefs you can't look at a class and make assumptions, the code becomes hidden and not in a good way (like encapsulation) but in a bad way (so you can't understand). Generics coupled with autoboxing will cause Java no end of pain because of bad code that will assume it makes use of primitives and multiple null pointer exceptions. This will happen because people won't understand whats going under the hood thus the simplicity of Java is lost and we can't get it back. So no, even if we don't use generics we will pay a price for their existence!
  23. Heinz asked his 8000 subscribers, and 80% of the respondents said YES.
    How many of those 80% used generics? I'm sure some of them ran this cool TestGen.java class they wrote in two minutes with plain vanilla generics and autoboxing...
    I asked the people who said they were easier whether they had used them in real projects, and you were right - most of them had not. This is precisely why I am posing the question :)

    I did notice that alot of those who like generics used IntelliJ, whereas the people who did not like generics were often working with VI / notepad / etc.
  24. About the typedef idea: its one of the things I despise the most about C++. When looking at Java code you could easily tell what would happen:

    z = a + b;
    This has nothing to do with typedefs.
    By using typedefs you can't look at a class and make assumptions, the code becomes hidden and not in a good way (like encapsulation) but in a bad way (so you can't understand).
    Please explain to me the difference between typedef and defining a new class.

    If I write

    User u = new User();

    why do you care if User is a typedef or a class?
    Generics coupled with autoboxing will cause Java no end of pain because of bad code that will assume it makes use of primitives and multiple null pointer exceptions.
    Why would autoboxing make it more likely that we will be seeing more NullPointerExceptions?

    --
    Cedric
    http://beust.com/weblog
  25. About the typedef idea: its one of the things I despise the most about C++. When looking at Java code you could easily tell what would happen:z = a + b;
    This has nothing to do with typedefs.
    No it has nothing to do with typedefs but a typedefs example will be much larger. The concept is identical, you look at code and it isn't immediately apparent what it means:
    MyType x;

    Would always mean in java that x is an instance of class MyType that exists in one of the packages imported by the java source file and unless it is in the current package I can always find this class in MyType.java. So yes I can use:
    find src -name "*.java" | xargs grep -l MyType
    And I can find the typedef definition that can mean anything. A typedef can be a generic definition which would mean additional complexities when I want to rely on the code for multi-tier applications.

    A good example here would be a class that I would like to exist in two tiers, yet I want one tier to be as small as possible. So rather than just package MyType, I'd have to know that it is a typedef and find all the classes involved (it may be a generic class with several dependent classes). Turns out that I use this class right on program startup and cause 50 classes to load...
    This is the thing I DESPISE about C++! You don't know what you are doing, and IMO this is ridiculous. There is a thick line between encapsulation and hiding stuff that the developer HAS to know, typedefs are glorified macros and macros are evil. They hide information in order to save typing causing everyone to reinvent their own form of incompatible types and adding to the general confusion within the ranks.

    So yes, understanding complicated definitions is hard. But people should immediately see what their code is doing, its harder to start but easier as you go along. The code may be longer but it is clearer in some aspects.
    By using typedefs you can't look at a class and make assumptions, the code becomes hidden and not in a good way (like encapsulation) but in a bad way (so you can't understand).
    Please explain to me the difference between typedef and defining a new class.If I writeUser u = new User();why do you care if User is a typedef or a class?1. Performance - rather than load one class I can load several (yes its true with a regular class as well).
    2. Useless syntax sugar.
    3. Indirection - in order to actually look at the underlying class you have to first find the typedef and then find the code.

    I find that the people that like typedef's are the people that spend their time developing frameworks for other people. Typedefs advocates promote the "you don't need to know" mantra. The problem is that this mantra is dead wrong, we all need to know what our code is doing. More importantly we need to know what our code is doing fast, hiding behind a typedef simply makes the code UNREADABLE because it tries to hide information that should readily be available to the user. If you want to encapsulate information use a class!
    Generics coupled with autoboxing will cause Java no end of pain because of bad code that will assume it makes use of primitives and multiple null pointer exceptions.
    Why would autoboxing make it more likely that we will be seeing more NullPointerExceptions?Among other things: Map<Integer, Integer> a;
    int b = a.get(1);

    This will translate to
    int b = ((Integer)a.get(1)).intValue();

    Which will fail because 1 doesn't exist... There is no decent solution for this flaw.

    Autoboxing does the exact thing I advocate against, it makes the code look simpler on the outside while the underlying code is far more complex. This means that people will THINK they understand Java faster but will fail to use Java correctly. IMO this does not simplify Java, on the contrary it makes it considerably harder by adding pitfalls and hidden code to something that looks misleadingly simple!
  26. So yes, understanding complicated definitions is hard. But people should immediately see what their code is doing
    I think everybody agrees with this but you would be surprised at how it can be interpreted. For example, if you say this to a C programmer, he will laugh at your face and explain to you how much Java hides things.

    You need to understand that such considerations are exceptionally subjective, and the only way to arbitrate on them is to get consensus from a lot of people. The new features added to JDK 5.0 received this consensus many years ago.
    So yes I can use:
    find src -name "*.java" | xargs grep -l MyType
    Ugh, you don't actually use this to navigate your Java code, do you?
    If I write
    User u = new User();
    why do you care if User is a typedef or a class?
    1. Performance - rather than load one class I can load several (yes its true with a regular class as well).
    Then you just said that performance is the same...

    Again: I don't want typedefes in Java as I explained in the blog entry I posted above, but your argument above doesn't make sense to me.
    2. Useless syntax sugar.
    If it replaces Map<String, List<Name>> with User, it's certainly not useless to me and it improves readability quite a lot.
    3. Indirection - in order to actually look at the underlying class you have to first find the typedef and then find the code.
    There is absolutely no difference in locating a typedef from a class definition (assuming you are using modern tools, and if you're not, it's still a simple find).

    All the reasons you give for not liking typedefs are wrong-headed, in my opinion...
    This will translate to
    int b = ((Integer)a.get(1)).intValue();

    Which will fail because 1 doesn't exist... There is no decent solution for this flaw.
    I asked why you thought that autoboxings would cause NullPointerExceptions that didn't exist in the code in the first place. There is an NPE lurking in the code above, so if anything, autoboxing will make it appear *sooner*.

    Without autoboxing, your get() will return a null that you will dereference later in your code and that you'll have to trace back to... this get(). Autoboxing will give you this error right away.

    So I ask again: why do you think that autoboxing will create new NullPointerExceptions that didn't exist in the code without it?

    --
    Cedric
    http://beust.com/weblog
  27. So yes, understanding complicated definitions is hard. But people should immediately see what their code is doing
    I think everybody agrees with this but you would be surprised at how it can be interpreted. For example, if you say this to a C programmer, he will laugh at your face and explain to you how much Java hides things.You need to understand that such considerations are exceptionally subjective, and the only way to arbitrate on them is to get consensus from a lot of people. The new features added to JDK 5.0 received this consensus many years ago.
    I'm working on a porting project right now and do a fare share of C, I have extensive J2EE and J2SE experience as well. And I disagree, Java hides nothing. The VM is Very clear about everything that happens. In C on the other hand, we have global variables, macros and pointers/function pointers that can be manipulated everywhere in the code.

    About consensus, thats just wrong. IBM was very clear about the fact the they did not agree with generics and that it was redundant. I'm quite sure Gosling was against it morally but joined the partyline since C# has generics and its an image thing rather than a technical thing.
    Furthermore if this argument states that most people wanted generics, then yes there probably was a consensus, consisting mostly of people who didn't know what they were signing up to. If you will go to 100 "typical" Java programmers out there and give the "real" projects with generics and these extra features, I doubt they will be as happy with these features when they finish.
    So yes I can use:find src -name "*.java" | xargs grep -l MyType
    Ugh, you don't actually use this to navigate your Java code, do you?
    No, I usally use more complex sed scripts to find some things ;)
    I use GUI when its faster and command line when I need to find complex things that are hard to express in GUI.
    All the reasons you give for not liking typedefs are wrong-headed, in my opinion...
    Java IMO is a very low level language. You (up until now) always knew what you were doing in the VM level, so sure there were some irregularities with the memory model but generally when you see some block of code its strait forward. More so than even C (obviously more than C++/C#). Typedef's mean I have to first guess that something is a typedef and not a class then find that typedef then find the class (probably classes) that it uses. This is all in the name of simplifying things for me (the dumb programmer who needs to maintain code). This is an attitude I depspise, the need to hide. It may look simpler on the surface, but for a maintainer that actually needs to maintain 10 year old code it is a huge pain and a lie. I've been there and had to dig through typedefs, enums and macros and the code is far less readable because its missleading.
    Autoboxing will give you this error right away.So I ask again: why do you think that autoboxing will create new NullPointerExceptions that didn't exist in the code without it?
    Would a typical programmer see that this code:
    int a = map.get(1);

    has a null pointer exception in it??? Java has spoiled us, up until now if a null pointer exception was thrown from this line (we got the exact line number sometimes) then we could tell with 100% certinty that the map is null! No more, people need to be prepared for this when they have no pointers... This is meant to "simplify" the work of beginners?
    I don't think the compiler should do my work for me.
  28. And I disagree, Java hides nothing.
    Again, it's a matter of perspective. Show "String s = s1 + s2" to a C programmer and they will cry in despair, telling you that such an expensive operation should be in the face of the developer with a strcat().
    No, I usally use more complex sed scripts to find some things ;)
    I use GUI when its faster and command line when I need to find complex things that are hard to express in GUI.
    In my experience, GUI search is *much* more powerful than anything you can come up with sed and find.

    For example, how would you locate all the invocations of the method sendMessage(int n) but not the overloaded version, the one that accepts two parameters?

    Good luck without an IDE.
    Java IMO is a very low level language.
    Let's just say that your opinion is not shared by many, as Java is typically seen as a Fourth-Generation Language. For example, the following languages/classes of languages are usually acknowledged as lower-level than Java, in order of decreasing level:

    - Any language that doesn't run on a VM
    - C++
    - C
    - Assembly
    - Machine language

    I'll leave aside binary programming as a favor to you :-)
    Typedef's mean I have to first guess that something is a typedef and not a class
    I think that's the main thing you are missing: you don't *care* whether it's a typedef or a class, because it makes absolutely no difference (a reason why I think typedefs are useless in Java, one of the few points we seem to agree on).
    I don't think the compiler should do my work for me.
    Then you should use machine language. It will make you realize and appreciate how high-level Java is...

    --
    Cedric
  29. And I disagree, Java hides nothing.
    Again, it's a matter of perspective. Show "String s = s1 + s2" to a C programmer and they will cry in despair, telling you that such an expensive operation should be in the face of the developer with a strcat().
    Strings are a special case in Java, this is the case for most languages and moreso in Java. This isn't hidden, its predictable and its in the API layer and not within the language itself. The only thing that exists in the language is the + operator to concat immutable strings.

    In fact, JDK 1.5 improved the support for the String + operator by introducing an unsynchronized class. This change illustrates how the language can be changed under our feet without breaking compatability thanks to the very limited constraints within the language.

    I care deeply about performance and still write a bit of assembly code, I personally don't "cry in despair". Yes this is one of the things that people run into with Java "Strings cost", but why add more? In actuallity you are arguing my point, if Strings in Java are bad in your opinion, then why do we need other slow operators for convenience?
    In my experience, GUI search is *much* more powerful than anything you can come up with sed and find. For example, how would you locate all the invocations of the method sendMessage(int n) but not the overloaded version, the one that accepts two parameters? Good luck without an IDE.
    I never said I don't use an ide??? I use quite a few of them and their search features quite often. However, I find that sed/grep/find are usually faster than importing every bit of code into an ide... See, we work on MANY projects and have archives of projects dating back to the late 90's that are still active. Unlike one large old project here we have everything archived in the network, and sometimes we need to extract/examine code that no one (currenly working for us) has touched in ages.
    Since many of these projects are mixed code C/Assembly and Java and even those that are pure Java predate modern ide's. The build system and file organization is rather "imaginative", so yes if I were to build a project or work with it for more than a day I would take the hastle of organizing it into an IDE.
    Java IMO is a very low level language.
    Let's just say that your opinion is not shared by many, as Java is typically seen as a Fourth-Generation Language. For example, the following languages/classes of languages are usually acknowledged as lower-level than Java, in order of decreasing level:- Any language that doesn't run on a VM- C++- C- Assembly- Machine languageI'll leave aside binary programming as a favor to you :-)
    I consider Java low lever when compared to the VM. Java is to the JVM as C is to the OS and Processor. Fair enough?
    Since the VM is VERY predictable (unlike the OS/Processor) Java is very easy and provides great control.
    Typedef's mean I have to first guess that something is a typedef and not a class
    I think that's the main thing you are missing: you don't *care* whether it's a typedef or a class, because it makes absolutely no difference (a reason why I think typedefs are useless in Java, one of the few points we seem to agree on).
    You assume that closed library code is fail safe and bug free? When I need to go back and examine the code I need to understand whats going on. I don't know whether one thing is important or not. So if someone used a typedef thats additional time I have to spend investigating the code rather than working.

    I don't care about anything when code works properly. Our discussion is about a situation where something fails and you need to trace back which is 90% of the application development time in my experience.
    I don't think the compiler should do my work for me.
    Then you should use machine language. It will make you realize and appreciate how high-level Java is.
    Let me rephrase that, I don't want the compiler to "make decisions for me"/"think for me". I want it to do optimizations and operations that I instructed it to do, but I don't want it to be too imaginative.

    I think you understood what I meant, no need to be petty ;)
  30. <blockquoteblockquote>This will translate toint b = ((Integer)a.get(1)).intValue();Which will fail because 1 doesn't exist... There is no decent solution for this flaw. I asked why you thought that autoboxings would cause NullPointerExceptions that didn't exist in the code in the first place. There is an NPE lurking in the code above, so if anything, autoboxing will make it appear *sooner*.Without autoboxing, your get() will return a null that you will dereference later in your code and that you'll have to trace back to... this get(). Autoboxing will give you this error right away.So I ask again: why do you think that autoboxing will create new NullPointerExceptions that didn't exist in the code without itBecause with autoboxing I write

    int b = a.get(1); // wrong!

    With no autoboxing I write:

    int b = -1;
    Integer integerB = a.get(1);
    if (null != integerB)
      b = integerB.intValue();
    // much uglier, but correct

    Another way with autoboxing now has to be:

    int b = -1;
    try { b = a.get(1); } catch (NullPointerException e) {}

    So how is my code better now? What if my Map implementation has a bug that is now obscured? How do I get around this problem?

    Maybe:

    int b = -1;
    if (a.containsKey(1)) {
      b = a.get(1);
    }

    but this is not right, because the value could be null. You need to do this:

    int b= -1;
    if (null != a.get(1)) {
       b = a.get(1);

    Or

    b = (a.get(1) != null) ? a.get(1) : null;
  31. Correction[ Go to top ]

    b = (a.get(1) != null) ? a.get(1) : -1;
  32. generics[ Go to top ]

    IMO generics will make code much more self-documenting. Ive lost count of the number of times Ive had to read implementation code to discover what type of objects are going to be returned by an API method with a continer return type. Somtimes Ive even had to resort to writing a test app to make the call and then introspect the container elements - this total crap. Now whenever I come accross a container reference I can just browse to the declaration and know exactly what s going to be in there.

    Paul.
  33. good point[ Go to top ]

    though I'm kind of against generics, I think your point is a good one. It IS often a problem in Java to know what a collection contains (Set of Strings, Set of Numbers, Set of Lists of Strings).
  34. Generics are annoying[ Go to top ]

    Here is my post on it many months ago:

    http://www.javarants.com/C1464297901/E1994239229/index.html

    Sam
  35. Generics are annoying[ Go to top ]

    Agree 100%.

    With generics (and java.util.HashMap code as exhibit A) it is the first time in the history of java that you have this kind of complexity at the syntactic level...

    The worry is that we will have the kind of write-once read-never code that we had in C++....

    Too much rope, in my view...

    -Nick
  36. Generics are annoying[ Go to top ]

    Agree 100%.With generics (and java.util.HashMap code as exhibit A) it is the first time in the history of java that you have this kind of complexity at the syntactic level...The worry is that we will have the kind of write-once read-never code that we had in C++....Too much rope, in my view...-Nick
    I liked your comment - "write-once read-never" ;-)

    Indeed, I personally find the new collection classes of JDK 1.5 more difficult to quickly scan through than previously. Granted, I am not used to generics yet, but I think that even when I am, it will take me a good deal more time to work my way through an implementation of java.util.HashMap than before. I actually catch myself going back to JDK 1.4.2 sources so that I can at least see what the gist is of what the classes in JDK 1.5 are supposed to do.
  37. side question[ Go to top ]

    All,

    Sort of unrelated but in the code example he used a class called Exceptions. I have seen pro and con for this type of centralized exception thrower.

    My current feeling is that there is no easy way to have a single method of throwing or dealing with exceptions. Yes its annoying to have to deal with them all over the place but in general i ignore them unless i can deal with them, i.e. let them propagate up (unless i am main or something).

    It seems possible to create a robust exception thrower, but could use peoples thoughts.

    Sorry if this is somewhat off topic.

    Bruce
  38. side question[ Go to top ]

    I pretty much do the same, and here're a few rules I follow:

    1. Throw checked exceptions if the client code can make use of them, and if they have a chance at recovering from the exception.
    2. Catch system exceptions and wrap them in my own application exceptions when it makes sense.
    3. Let exceptions bubble up the call stack if there's not much I can do other than logging it.
  39. side question[ Go to top ]

    All,Sort of unrelated but in the code example he used a class called Exceptions. I have seen pro and con for this type of centralized exception thrower.My current feeling is that there is no easy way to have a single method of throwing or dealing with exceptions.
    I use the central Exceptions handling construct extensively. I even have my default try/catch code-completion in IntelliJ set to:

    try {
      // some code
    } catch(IOException ex) {
      Exceptions.throwException(ex);
    }

    or something like that.

    Whilst in the ideal world, we would be able to write perfect exception code every time, in the real world, it is frequently difficult, if not impossible to get it right. My central exceptions handler is my alternative to

    ex.printStackTrace();

    and

    throw new RuntimeException(ex);

    I think the central handler is a better of those three options. I have seen more bugs in error handling code in Java than anywhere else.

    Obviously, I would try to handle the exception 100% correctly, but where I cannot, I use the central handler.

    See also Catching Uncaught Exceptions in JDK 1.5

    It seems that Sun has either recognised the error of their ways (by patching checked exceptions onto the exceptions hierarchy after starting with unchecked exceptions in Oak) or they realised that a lot of programmers would prefer to have a central place to moan to when an exception occurs that they cannot deal with.
  40. I think that somebody else here made a good point. 80% of people said that generics were a good idea. How many of those 80% have actually used generics on a sizable Java project? I suspect that many of those who responded were probably basing their response on their experience of C++ templates.

    It's part of a general trend which I've been suspicious of in Java over the past few years. A lot of projects which would have used C++ some time ago are now using Java. So a lot of C++ programmers are moving into Java. And they want Java to have the same constructs (templates, enums, variable parameters, const parameters, typedefs, structs, whatever) that they're used to in C++. Java is slowly turning into C++, becoming larger, more complex, harder to learn, harder to read. The old ideal of a tight, streamlined, simple language seems to be getting lost.

    Lets face it, most of the people reading this forum are average developers. We all like to think we're in the top 10% but at the end of the day for the vast majority of us that simply isn't true. My memory of the C++ programs I used to work on that used templates is that most people (me included) thought they understood them, but damn few people really did.
  41. Yes, Generics make code easier to maintain?[ Go to top ]

    80% of people said that generics were a good idea. How many of those 80% have actually used generics on a sizable Java project?
    Well, I didn't vote, but I've been flirting with Java Generics for years now, and I have been seriously using them for at least six months on a codebase that is now approaching 1MLOC. My personal experience is that Java Generics do increase maintainability - especially in the face of complex data structures.

    I keep on hearing complaints that HashMap<String,Map<Integer,List<String>>> is so much more difficult to read than plain old HashMap, but I promise you that I'd prefer the first any day of the week over trying to deduce that information from an unparameterized declaration.

    There are plenty of things to dislike about Java Generics (don't even get me started), but some kind of imagined complexity sure isn't one of them.

    God bless,
    -Toby Reyelts
  42. There are plenty of things to dislike about Java Generics (don't even get me started), but some kind of imagined complexity sure isn't one of them.God bless,-Toby Reyelts
    Toby, I agree with most of your comment, but while it may not be your intention the word "imagined" doesn't feel appropriate to me.
    When talking about complexity we talk not just about the syntax but the overall:

    1. Explaining things like the inconsistencies in the API since generics were added so late.

    2. The JavaDoc and definitions become far more verbose.

    3. There are complexities with interaction with non-generics code.

    4. There are warning that will confuse newbies.

    Obviously syntax such as <? extends T> is far from ideal...
    The complexity we talk about is in relation to what we get in return HashMap<String,Map<Integer,List<String>>> would be bad regardless of generics. Generics won't solve any technical problem, they will just change the syntax. I'm a purist and feel the language should be clean and the API large, thats why I dumped C++ 8 years ago for Java.

    The problems that we have with generics are mostly a matter of opinion, I'm sure that once more people use generics most of them will change their mind about them and I think you are the exception rather than the rule.

    Quite a few generic advocates agree with me from the other side, while they want generics in Java they agree that the current implementation is terrible. By allowing downcasting generics have opened a can of worms that will cause even reasonably experienced Java developers no end of frustration in years to come.
  43. I keep on hearing complaints that HashMap<String,Map<Integer,List<String>>> is so much more difficult to read than plain old HashMap, but I promise you that I'd prefer the first any day of the week over trying to deduce that information from an unparameterized declaration.
    Yes, but if the declaration is unparametrized, then in the code review you can force the developer to wrap the datastructure into some more meaninful objects. I have no clue what your Map<Integer, List<String>> represents, if you made a wrapper object for it (that would have a "String getXXX(Integer)" method then I would know exactly what your HashMap contains.
  44. I think that somebody else here made a good point. 80% of people said that generics were a good idea. How many of those 80% have actually used generics on a sizable Java project?
    I respect my readership a lot. The whole approach of "The Java Specialists' Newsletter" is that this is a publication written for proficient, no, specialist Java programmers (note the placement of the ' on Specialists). As a result, we have few subscribers, but some of the best Java experts in the world.

    That said, generics are new, and most of my readers are practitioners, rather than theoreticians. Most, no all, of my customers are still using JDK 1.4.x, and there are some on JDK 1.3 (and before) still. So, I do not bring practical experience in a sizable project to the table.

    I had the same suspicion as you, so I emailed each of the voters and asked them if they had worked on a sizable Java program with generics. Only one responded that he had actually used them, but in an open-source project, rather than a commercial one.

    I am hoping to elicit some good comments (like we have already had) from someone who has worked with generics in the real world on a real project.
  45. Generics as part of growing Java[ Go to top ]

    An interesting article on why generics for Java

    http://homepages.inf.ed.ac.uk/wadler/steele-oopsla98.pdf
     
    It seems the next change to Java will be operator overloading and user-defined types of light weight.
  46. Re: Generics as part of growing Java[ Go to top ]

    Operator overloading? User defined types? Generics?

    C++ has them all! Use that instead of Java!!

    All of these features you mention are useful for things like low level data structures, they are NOT useful at the business object level and just obfuscate the code.

    User defined types is just a stupid idea. Java is an OO language where types are defined as classes. You want a new type.. define a class.. too much work? Get a new IDE that can generate your new type as a macro..

    Many people lament that Java has primitive types (instead of staying pure OO and optimizing at the compiler level). You want to add names to your types now??

    I just don't understand this logic. If you want C++ use C++. If you want C use C. Why does Java have to be something it is not! We might as well as for malloc() and free() too!
  47. Having read all I could find about Generics, I realized that Generics could be used for lot more than handling collections and lists.

    I realized that Generics could be used for "conceptual programming", something I have always been missing in Java. What is "conceptual programming"? Well, say you define an "interface" that uses a <code>Signature</code> for certification reasons. As a framework(interface) provider, you do not want to say which Signature class or interface. You like different implementors provide implementation classes and interfaces to Signature. With Generics you can do this. But.....

    Based on the above, I made a decision and converted my entire code to Generics. It took me a long time to convert. When the conversion was finished, I decided to go back to old good Java. So I converted back. The following summarizes my experience:

    1. As of this writing, JDK/IDE's are not good enough to point out all the holes (un-safe types) you create by using Generics. (I used eClipse, it helped a lot, but not enough). So it works against its purpose.
    2. The syntax of Generics is difficult to read and understand. Most novel programmers already have problem with the complexity of Java. Generics does not certainly make it better.
    3. In my humble opinion, Generics creates more problems than it solves.
    4. Generics is very good when you simply work with objects of type "Object" like collections. Note that your implementation must be good enough if the client code forgets to use the Generics syntax.

    Future:
    1. I hope that JDK/IDE's become much better such that it is not possible to create un-safe holes into the code.
    2. I hope that community comes up with good examples of Generic code that is not necessarily about colllections and lists. In particular, examples about how you can create "conceptual code".