Why is Java not ‘pure’ OOP? [duplicate]

Java is designed in a very OO approach, and somewhat even ‘forces’ programmers to program within the OO paradigm (which can be considered good or bad, a matter of opinion).

However while almost everything in Java is a class or an object, primitive data types (int, double, etc) are not.

While I see no advantages to this, there are disadvantages. For example, when a method wants to take in as a parameter ‘any value’, it usually declares the parameter of type Object, the supertype of all classes in Java. However if the programmer wants to input an int to the method – a perfectly valid value – he/she has to ‘box’ the value in an instance of the Integer class, created specifically for these kinds of needs (as far as I understand).

My question is: why aren’t primitives in Java classes, like everything else?

2

There are trade offs to be had in every design choice.

When you have a “pure” OO language (see if you can get anyone to agree on what that is), when you do addition, rather than having the system get two numbers and add them, you are instead first invoking the add method on the object and getting back a new one (making mutable Number Objects can make for difficult times).

An example of this would be the BigInteger class. Instead of int fourtyTwo = 6 * 7; you’ve got BigInteger fourtyTwo = new BigInteger(6).multiply(new BigInteger(7)); You’ve created a total of three objects and done some math in the background. This is also a little bit of a mess, but thats just the semantics – you can hide that with operators, but its still doing all that work behind it.

From C2 Is Java Object Oriented the reason becomes clear:

Lastly, it is a hybrid to provide performance gains. Even though Smalltalk has an advanced virtual machine, its inability (when I was using it) to provide a machine-correlated bytecode for integer math placed a significant performance impact on its entire environment. Being a hybrid, Java cannot be called a true Object-Oriented language. But then, why does it matter? 😉 Use the right tool for the job and life will be happy!

You can see what is being mentioned there in some docs for SmallTalk:

Thus, math is not a special case in Smalltalk; it is done, exactly like everything else, by creating objects, and sending them messages. This may seem odd to the Smalltalk novice, but this regularity turns out to be quite a boon: once you’ve mastered just a few paradigms, all of the language “falls into place”. Before you go on to the next chapter, make sure you try math involving * (multiplication), – (subtraction), and / (division) also. These examples should get you started:

While yes, it does men that some things can be more elegant in the language design it also means that its going to be slower. From a talk on SmallTalk and Objective C:

What makes things slow?

  • Small integer arithmetic
  • Boxing
  • Dynamic message lookup
  • Memory management operations

Another example of this performance can be seen at the Language Benchmarks Game for Ruby vs Java – where Ruby implements the “pure” OO style math – messages are sent to the object to add rather than working with primitives. Note that in many cases Ruby is one or two orders of magnitude slower than Java. These benchmarks are all math heavy, and when looking at the Java code, they’re all using primitives.

There are things you can do to speed that up, but its still less than optimal. Early Java was plagued by performance concerns. Making math that much slower would have been awful.

Lets look at a high performance Java architecture: LMAX. Every iota of performance was pulled out of this, in some cases rewriting some rather basic things.

It took a bit more cleverness to go up another order of magnitude. There are several things that the LMAX team found helpful to get there. One was to write custom implementations of the java collections that were designed to be cache-friendly and careful with garbage. An example of this is using primitive java longs as hashmap keys with a specially written array backed Map implementation (LongToObjectHashMap). In general they’ve found that choice of data structures often makes a big difference, Most programmers just grab whatever List they used last time rather than thinking which implementation is the right one for this context.

Writing a HashMap that could work on <long, Object> rather than <Long, Object> allowed for some significant performance gains by not having to do object based equality for two objects (could just use ==) and avoiding a number of issues with garbage collection (look at your heap some time and count how many Long objects are sitting around when you’re heavily using HashMaps).

Lastly consider that Java’s hotspot optimizer will compile code to native when it needs to. The code produce by int fourtyTwo = 6 * 7 is much simpler and faster than the corresponding BigInteger fourtyTwo = new BigInteger(6).multiply(new BigInteger(7));

Its all about trade offs, and this was one where performance won out over “pure” elegance.

5

Quoting an answer of mine in another question.

In some cases language designers make compromises for usability’s sake.

Numbers are used too often. Having to instantiate them all the time would make the language too verbose.

There a few other examples of special exceptions made for the sake of usability:

Objects of type String can be instantiated without new, event when String is not a primitive:

String s = "Hello";

String being a non-primitive, should be instanciated like this:

String s = new String("Hello");          // this also works 

But the compiler allows for the shorter, less OO option, because String is by far the most widely used class in the API.

Also arrays can be initialized in a non-OO way:

int i[] = {1,2,3};

Weird enough, an object is either an instance of a class or an array. Meaning arrays are a completely separate type of class.

Arrays have a lenght public field which is not a constant. Also there’s no documentation on the class arrays are an instance of. ( not to confuse with Arrays class or java.reflect.Array ).

int a = myArray.length;    // not length()

5

One core principle of OOP is that values (not just variables) have types, which is a requirement for dynamic dispatch. Each object is tagged with a type. This tag is usually a pointer to a structure representing a class. In Java, objects have further overhead to facilitate synchronization, but lets be aware that each object has to at least carry a pointer (4 or 8 bytes) around together with the actual data. This alone doubles or quadruples the size of a primitive like int! Having primitives that aren’t real objects is therefore very desirable from a performance standpoint.

Having primitives is not a problem – C# is very similar in that respect, except that real autoboxing makes explicit companion classes like Integer unnecessary.

In Java there is also some connection between primitives and generics. Due to Java’s history, generics have been implemented using type erasure: at runtime, there is no difference between a List<Foo> and a List<Integer>, as the generic types are only checked during compilation. In reality, such generic collections just contain Objects. Generics can also be implemented efficiently using specialization (which is how templates in C++ work). As we can now figure out whether we have a List<Foo> or List<int>, we can use compact storage for primitive types (or in principle other sealed/final classes). Java can’t do that, so we need full blown objects when storing primitives in collections – here, an Integer wrapper.

Such issues with generics were not on the horizon when Java was first released. Gradually, more and more autoboxing behaviour has been added to make this divide less visible.

I think the only reason is that it is complicated for the compiler writer.

I mean, you could have a system where every primitive type was used in the language as if it were any object with all the “elegance” and convenience that entails. So a call to string s = i.ToString(); would become a call to the equivalent static function string s = ToString(i); as a simplistic example.

However, you’d have to tell which types were primitive and which were not; you’d also have to ban inheriting from these (or you could get in all kinds of a mess); and even then some people would create their own pseudo-primitive types and expect them to perform with the speed of primitives.

But I think some aspects of objects would prove to be too difficult to implement in such a fashion for primitives – garbage collection requires all objects be created on the heap and referenced and the interfaces that are expected by method calls wouldn’t necessarily work if there wasn’t a real interface to call through (ie each object needs a vtable which our primitives-as-objects wouldn’t have)

So boxing is a workaround that was added. I think the C++ way is better – no boxing required there and you can mix primitives and objects easily. Java went for a higher level abstraction and this way of having to work with primitives differently is just another example of real world impacting on our desire for perfection.

2

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật