User:Tentor
Jump to navigation
Jump to search
Java sucks because:
Syntax
- Overly verbose.
- Java has unused keywords, such as
goto
andconst
. - There's no operator overloading... except for strings. So for pseudo-numeric classes, like BigInteger, you have to do things like
a.add(b.multiply(c))
, which is really ugly. - There are no delegates; everytime you need a function pointer you have to implement a factory design.
- Before Java 7,
catch
clauses can contain only one exception, causing a programmer to rewrite the same code N times if she wants to react the same way to N different exceptions. - The
return
statement is not valid within initialization blocks. - Arrays don't work with generics: you can't create an array of a variable type
new T[42]
or of a parameterized typenew ArrayList<String>[42]
- No properties. Simple class definitions are 7 to 10 times as long as necessary.
- Before Java 7, there is no automatic resource cleanup; instead we get have five lines of "allocate; try {...} finally { cleanup; }"
- No array or map literals.
Model
- No first-class functions and classes.
- Checked exceptions are an experiment that failed.
- There's
int
types andInteger
objects,float
types andFloat
objects. So you can have efficient data types, or object-oriented data types.- Number base-class doesn't define arithmetic operations, so it is impossible to write useful generics for Number subclasses.
- Using only interfaces to implement multiple inheritance doesn't allow to share common code through them, unlike "mixins".
Library
- Functions in the standard library do not use consistent naming, acronym and capitalization conventions, making it hard to remember exactly what the items are called:
java.net
hasURLConnection
andHttpURLConnection
: why notUrlConnection
orHTTPURLConnection
orHttpUrlConnection
?java.util
hasZipOutputBuffer
andGZIPOutputBuffer
: why notZIPOutputBuffer
orGnuZipOutputBuffer
orGzipOutputBuffer
orGZipOutputBuffer
?
- The design behind
Cloneable
andclone
is just broken. - Arrays are objects but don't properly implement
.toString()
(if you try to print an array, it just prints hash code gibberish) or.equals()
(arrays of the same contents don't compare equal, which causes a headache if you try to put arrays into collections) - Useful methods like sorting, index of, binary search, etc. are not part of Collection classes, but part of separate "utility classes" like
Collections
andArrays
- Why is
Stack
a class, butQueue
an interface? - Code is cluttered with type conversions. Arrays to lists, lists to arrays, java.util.Date to java.sql.Date, etc.
- The Date API is considered deprecated, but still used everywhere. The replacement Calendar is not.
- No string join function.
- The reflection API requires multiple lines of code for the simplest operations.
Disputed
Some points in this section have been disputed on the discussion page.
- Nearly everything is wrapped with objects and many things must be buffered, even those things that don't really need to be objects or be buffered. (examples?)
- Some interfaces such as
Serializable
andRandomAccess
are used just like annotations: they are empty, and when implemented their only purpose is to indicate some semantics.- An interface describes how an object can be used, even if it does not add any methods. From an OO perspective, there is nothing wrong with that.
- They were introduced before annotations.
- It is not possible to un-implement the interface, though.
- Initialization blocks (both static and non-static) can't throw checked exceptions.
- Arrays are not type safe:
Object[] foo = new String[1]; foo[0] = new Integer(42);
compiles fine but fails at runtime- array covariance exists in other statically typed languages as well
- Unicode escapes can have unexpected effects, because they are substituted before the code is parsed, so they can break your code, for example: (1) if a line-end comment contains a \u000A (line return), the rest of the comment won't be on the same line, and thus won't be in the comment anymore; (2) if a string literal contains a \u0022 (double quote), it ends the string literal, and the rest of the string is now in the actual code; (3) if a \u appears in a comment, and it is not a valid escape (e.g. "c:\unix\home"), it will cause a parsing error, even though it is in a comment
- Easily solved by using an IDE with syntax highlighting (or not using unicode escapes).
- Convenience functions must be overloaded for every fundamental type (e.g. max(float,float), max(double,double), max(long,long))
- Overloads for long and double are sufficient.
(removed)
- Interface method implementations are necessarily public, preventing to make an interface implementation accessible only to subclasses and same package classes. and You can't inherit a class as protected or private, your classes must publicly show everything they inherit.
- Also known as the Liskov Substitution Principle. If you don't want that, make it a composite.
- Afaik, no language except C++ supports that.
RuntimeException
inherits fromException
, but it doesn't make sense: checked exceptions are a special case of unchecked ones, not the contrary. Otherwise said, if I have to catch all the checked exceptions, why don't I have to catch the unchecked ones?- Does make sense, see Liskov Substitution Principle. If
CheckedException
would extendRuntimeException
a method that throws only (unchecked)RuntimeException
s might also throw checked exceptions. That would be broken. Think of it as every method declaringthrows RuntimeException
; thus, unchecked exceptions are the special case.
- Does make sense, see Liskov Substitution Principle. If
- Many standard classes do parameter checking and manually throw unchecked exceptions such as
NullPointerException
andIllegalArgumentException
. No problem; but what are the assertions for, then?- assertions are intended for internal consistency checks, can be disabled at runtime, and throw assertion errors. Thus, they must not be used for argument validation-
- Every, single, object, has its own synchronization monitor, even those that you never synchronize on, resulting in unnecessary resource consumption. If you declare the dummiest
ArrayList<Integer>
, each element of your array will have a synchronization monitor; and of course you will never synchronize on them. Do you have an idea of how many (totally useless) synchronization monitors there are in an instance of the virtual machine running a medium Java program? And in a big program, such as Eclipse or NetBeans?- performance argument is BS. There are zero useless monitors because the VM creates them only when they are needed.
- Instance initialization blocks cannot throw checked exceptions, there must be a no-arg constructor throwing those exceptions in its signature.
- Duplicate
- Can somebody in the universe explain me why the heck the
clone
method belongs to theObject
class instead of theCloneable
interface??- Yes, but it's not important. Removed as duplicate to "clone is broken"
- Cloning is a major pain, because the variable you are cloning must have a type that has a public clone() method (Object's clone() method is protected), which only exists for actual implementation classes, so you can't clone something of an abstract type (which kills abstraction). Also, all the clone() methods in the Java library return type Object for some ungodly reason (instead of the class's own type), so you have to cast it.
- replaced with link to article
- Enums in Java 1.5 are cool, but to use them you have to prefix the enum type, like
MyEnum.SomeValue
, because they exist in the enum class's namespace, so they are less convenient than just defining int constants- Enum constants belong to the enum, just like int constants belong to whichever class they are defined in.
import static MyEnum.*
solves the problem.
- Enum constants belong to the enum, just like int constants belong to whichever class they are defined in.
- Wouldn't it be better to make boxed type (Integer, ...) as efficient as the primitives (int, ...)
- They are as efficient as the value objects in any other OO language
- No meta-programming.
- not true.
- Programmers can be significantly more productive in Python than in Java
- Source is highly biased, many arguments are disputable. The overall argument of productiveness is a result of the individual points listed above. Productiveness is not the only criterion for a language (or C would be dead by now).