Hybrid Mobile App, Hybrid Communications Part 1

In your Android application, if you are using webView or cordovaWebView, you are probably using JavaScript in your HTML pages. However, using HTML pages and native pages separately will come in handy up to a point. At some time, it might be needed to make data transfer or function calling between those pages. In Android, native pages are written in Java while web pages use HTML, JavaScript etc.. In this post we are going to run a JavaScript function from Java, and send some data from Java to JavaScript!! More specifically, let’s first achieve a page transition of HTML pages by using only native Android buttons.

Call JavaScript function from Java

In the middle of our app, there is a webView, which is all the hybrid part of the app. In order to get this challenge to work, we got to define some function in JavaScript. Let’s add two divs, which will be used as two separate pages:

        <div id="firstpage">//contents of page one</div>
        <div id="secondpage">//contents of page two</div>

Then, hide the second page in CSS file:


Now it’s time to write our main function which will do the opposite, i.e., hide the first page and show the second one. The snippet below right does it:

        <script type="text/javascript">
        function secondPage(){

The practice made here is actually the working mechanism of JQuery Mobile. In JQuery Mobile also pages are located in one HTML page which all have unique ID’s as separate divs. However the magic of “data-role=page” makes it through and no need for hide() or fade() remains. Anyway, we’ve just made this by only JQuery and now all we have to do is to trigger this. Calling this JavaScript from Java page is as follows;


As you see, it is the same as loading an URL to our webView. But we only call a function by this method. In the first image below, the hybrid “data” page is opened, and in in the second one, the hybrid “plugin” page is opened by Android buttons:



Send data from Java to JavaScript

This is a little bit harder than calling a function. Because we have to create a JSON object and transfer it. As you see in the images, I created an EditText in Android to enter a data, which will be sent to the hybrid window. First we have to get the input as a string, then convert to JSON. And we need a function that will read this JSON on JavaScript section. Let’s first write this simple function, assuming we will generate a JSON object with on field “Value”. This function will also set the text named “datatransfer” in HTML page with the data entered:

        function setJson(Jsonobj)
            var log="";	
            log = Jsonobj.Value ;
            document.getElementById("datatransfer").innerHTML = "Sent string: " + log;

Let’s then generate the JSON object. In more detail, let’s add this code that converts the data from EditText named “text” inside the listener of the “send” button:

        send.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                String s=text.getText().toString();
                JSONObject jObject = new JSONObject();
                }catch (JSONException e) 

What we did here is, i.e. what happened when “send” button is pressed is converting this data to JSON and receive it by the function written in JavaScript. Now we have to ignite it. We should call this function setJson() wherever we want in our HTML page:

        <p id="datatransfer" onclick="setJson()">Sent string:</p>	

Let’s visualize what we have done so far. In the first image, the word “hello” is entered to the EditText, and in the second image, when the user clicks on the text “Sent string”, it’s value changes by appending the string entered to “Sent string: hello”:



Google Material Design

Google recently introduced their new theme called “Material Design”. With this new theme, Google came up with some fundamental changes increasing app-user interaction. Throughout the development of this theme, the point has been to attach a material appearance to the apps and realistic surface view to the pages. Let’s mention a few of Google’s principles and then get into some fantastic details.

1. “Material is the Metaphor” Google aimed to provide users the feel of motion and add a material dimension to the app, based on the influence of pen and paper.

2. “Tangible Surfaces” Google aimed to expose the edges and surfaces to reveal the concrete features.

3. “Dimensional Affordances” Google aimed to feature the dimension, manipulating the light that builds the dimension, hence manipulating the shadow.

4. “Emphasize Actions” Google aimed to boost the significance of functional interface elements in the app, hence increase the user interaction.

5. “User-Initiated Change” as mentioned before, Google aimed to let the user dominate over all the actions in the app.

Now it’s time to review the changes brought with this theme. You can access the entire documentation of the theme from Google’s page . Below are the outstanding ones among them.

First of all, as I implied in the 3rd principle, Google is emphasizing the significance of lights. Here we adopt a convention that effective use of shadows will better enhance the feel of overall lighting. While it’s a piece of cake to adjust the shadows in Photoshop or CSS, it is no easy task in Android’s former themes. For this fact, Google added a “z” dimension over x-y. This z dimension determines how above our View will look at the Layout that it’s in:


Simply enough, with one line of code we can adjust the height of elements.


Aside from that, Google has suggested some conventions addressing user interaction. For instance, in the case when user clicks one of the buttons in a group, that button had better rise above to provide with a more realistic and augmented interaction. Similarly the wave effect upon user’s tap on a certain point, which Google designed with the influence of ink, can help build a better interaction. Also, a new view should open originating from the point the user tapped instead of the center of screen. Below are respectively the demonstrations of these examples;

What is more, Google added two new UI Widgets featuring Material Design properties. One of them is the RecyclerView, a more enhanced ListView, and the other one is CardView, which forms the basis of Material Design principles. RecyclerView is a Widget which has a better performance for dynamically changing lists. And CardView is a Widget that you can create a new layout inside. CardView has some XML features like shadow or border radius. Google’s suggestion for transition between activities is constistency. That means, it would create a negative impression for the app if the screen totally changes in activity transitions. There is a great video Google prepared for this. As seen below, the user is initially in a page where a table of images make up the screen. Upon selecting one, the new activity starts with joining new required features while bringing the image selected to the top. This way, the context change will not disturb the user.

In the end, Google presented this Android design theme as a result of their elaborate work. Even though there may be a labyrinth of codes running in the background (for example Google mentioned in I/O that, they formed the shadows taking light from various sources and then merging them), what is reflected to the user is merely a simple appearance. And it is now pretty easy to utilize this simplistic and realistic theme in our apps.

Developing iPhone/iPad Applications with Objective-C

iPhone and iPad are popular platforms revolutionizing the mobile platforms. While these platform offer standart buildin gps, connectivity, multitouch controls and accelerometer, they also implement a unique and yet different programing model. To build any application and publish them to famous App Store, developers need to code in Objective-C. Objective-C also comes with a full featured devolopment IDE called XCode. Besides the coding facilities in XCode, another tool is also integrated to design and build user interfaces, the Interface Builder.

In this seminar you will build applications for the iPhone/iPad platform, including:

iOS Technologies
Developer Tools: XCode Environment, features and tools
Building User Interfaces

Tarih : 7 Şubat 2014 / 13:30-17:00
Yer :
İTÜ Ayazağa Kampüsü ARI 3 Teknokent Konferans Salonu 34469 Maslak İstanbul (İstinye Park Karşısı)

Konuşmacı: Ecem Dalgıç
Katılım ücretsizdir.
Kayıt Gereklidir

Leap Motion: A small step or a giant leap?

I’ve been playing with Leap Motion for the last few days and here are my first impressions with this tiny device.

First, this is a great piece of hardware and there are tons of things to be done with it. However it doesn’t really have compelling software accompanying it and currently not really going beyond a geek device but still it is a great geek device!! Here are my feelings in a more visual way :)

As you might see, after the shipment my package moved to Paris from Czech Republic instead of coming to Istanbul. The unpacking and installiation was quite ‘appleish’. The intro and the included demos were very impressive. The first thing I expected was an out of box replacement for the mouse which this device is definitely not. After a while playing with all the apps, I realized currently most apps are just mimicking a mouse experience instead of creating a unique one for Leap. Leap motion is great device offering a new way of controls and it must be treated that way, just like the iphone first released.

The accuracy of the controller is great! You may realize it loses some finger when you do sharp moves but the accuracy is great for any idea and any app, well may be not for flying a real plane. The gem of this device is the sdk. It is designed in a beautiful way and the more you dig into api, the more you want to write code on it. The APIs are implemented and designed in a beautiful way.

After downloading the sdk from leap’s website all you need to do is to follow the guidelines to set up your favourite development environment.

I built some sample apps using Java so I’ll continue with the provided Java SDK. Looking at the sample app provided with the sdk, the first thing you will notice is you need to create a class which extends the com.leapmotion.leap.Listener class. Next create another class with the main method and create a  com.leapmotion.leap.controller.Controller and add your listener to the controller you just created.

// your custom listener class

SampleListener listener = new SampleListener();

Controller controller = new Controller();

// add your listener to the controller


The custom listener class which extends Listener needs to implement several methods.

class SampleListener extends Listener {
public void onInit(Controller controller) {
//can check if controller.isConnected() and decide how to proceed
public void onConnect(Controller controller) {
//this method is invoked after your code is connected to the device
//it is time to decide what to listen. You can register for swipe, tap, circle… etc
public void onFrame(Controller controller) {
// Get the most recent frame
Frame frame = controller.frame();
//this is where the fun begines, you can how many hands or fingers in the frame
//and what they are doing such as moves, gestures…
//lets see how many fingers are there in the frame
if (!frame.hands().empty()) {
Hand hand = frame.hands().get(0);
FingerList fingers = hand.fingers();
System.out.println(“Fingers ” + fingers.count());
//checking gestures is not much different
GestureList gestures = frame.gestures();
for (int i = 0; i < gestures.count(); i++) {
Gesture gesture = gestures.get(i);
if (gesture.type()==Gesture.Type.TYPE_SWIPE){
SwipeGesture swipe = new SwipeGesture(gesture);
if (swipe.state()==swipe.state().STATE_START){
float x=swipe.direction().getX();
float y=swipe.direction().getY();
float z=swipe.direction().getZ();
System.out.println(“Swipe started at: “+ x +”, “+ y +”, “+ z);
if (swipe.state()==swipe.state().STATE_STOP){
float x=swipe.direction().getX();
float y=swipe.direction().getY();
float z=swipe.direction().getZ();
System.out.println(“Swipe finished at: “+ x +”, “+ y +”, “+ z);


As you might see its pretty easy to detect hands, fingers and gestures. Combining those Java’s Robot class you may end up with a simple mouse replacement app for Leap Motion or integrate some gestures to your favourite IDEs debugger to debug your code with simple gestures.

Leap Motion is a giant leap as a hardware unit which currently comes with a small step in software. However the opportunities are endless and what can be done with this little device is all up to your imagination!

Android API Fun

Android team have a good sense of humor and adding funny method or variable names to the API since from the first day.
Below I compiled a list I have came across don’t hesitate to post the ones I’ve been missing.

public static final float GRAVITY_DEATH_STAR_I

This constant is a member of  SensorManager class since api level 1 and gives the estimated gravity of the first Death Star (in Empire units!).

Constant Value: 3.5303614E-7

public static final float GRAVITY_THE_ISLAND

This constant is also a member of SensorManager class since api level 1 and gives the gravity on the island. Which island you ask? The lost island (from the TV series Lost).

Constant Value: 4.815162

public static int wtf (String tag, Throwable tr)

wtf method is a member of Log class since api level 8 and luckily doesn’t stand for the f word. According to the Java Doc and developer.android.com wtf stands for “what a terrible failure”.

public static boolean isUserAMonkey ()

isUserAMonkey method is a member of ActivityManager class since api level 8. This method can be used to determine if the user is a real user or an automated test (well, unless you are developing apps for real monkeys).

public void fyiWillBeAdvancedByHostKThx ()

fyiWillBeAdvancedByHostKThx method is a member of AdapterViewFlipper since api level 11. This method lets AdapterViewFlipper to prepare by no longer advancing its children. Instead it indicates it will be automatically advancing the the views of the AdapterViewFlipper to AppWidgetHost.

public boolean isUserAGoat ()

isUserAGoat method is a member of UserManager since api level 17 and it simply return true if the user is goat :) and according to the api documentation “Used to determine whether the user making this call is subject to teleportations”. Basically the method is an easter egg and unless you are messing up the interface it will return false.

Thats my collection so far, feel free to add yours or stay tuned for the upcoming version of the Android to bring some new ones.

Hybrid Mobile Uygulama Geliştirme Semineri-Ankara

Native mobil uygulama ilgili cihaza özgü dil ile yazılan (örneğin iOS için Objective-C, Android için Java) ve sadece ilgili cihazda çalışacak şekilde derlenen mobil uygulamadır. Native uygulamalar cihazın tüm fonksiyonlarına erişebilirler.

Mobil Web Uygulaması ise HTML5, CSS3 ve JavaScript ile yazılmış ve tarayıcı üzerinde çalışan uygulamadır. Web uygulaması, bir web server üzerinden yayınlanan web sayfaları şeklinde düzenlenir. Bu şekildeki bir uygulama cihazın sınırlı sayıda fonksiyonuna erişebilir.

Hybrid mobil uygulama ise bu iki kavramı birleştirmekte ve cihaz fonksiyonlarına  JavaScript ve Html5 ile erişilebilmesini sağlamaktadır.

Hybrid mobile uygulama kavramlarının anlatılacağı ve demolar eşliğinde gerçekleştirilecek bu seminerde aşağıdaki başlıklar üzerinde durulacaktır:

  • HTML5
  • Javascript
  • Phonegap
  • Design for mobile
  • Debugging
Tarih : 11 Temmuz 2013 / 13:30-17:00
Yer : Hilton Oteli 

Tahran Caddesi No:12 Kavaklidere Ankara

Katılım ücretsizdir.Kayıt İçin:



Murat Yener

Murat Yener, completed his Bs and Ms degree at Istanbul Technical University. Took part in several projects still in use in ITU Informatics Institute. Worked in Isbank’s Core Banking exchange project as J2EE developer. Designed and completed several projects still on market by Muse Systems. Worked in TAV Airports Information Technologies as Enterprise Java & Flex developer. Worked in HSBC as Project Leader responsible for Business Processes and Rich client user interfaces. Currently employed at eteration A.S. working on mobile platforms and Rich Internet Applications

Effective Agile Java Development

19-20 Haziran  tarihlerinde Eteration Academy olarak “Effective Agile Java Development” konulu bir eğitim düzenlemekteyiz. Eğitimin detaylarını aşağıda bulabilirsiniz.


0212 328 08 25

Effective Agile Java Development

This is an advanced and pragmatic workshop which will cover the latest agile development practices and tools that are used in Java™ Development.


This course is an advanced pragmatic workshop that teaches latest agile development practices and tools. It provides practical experience across the full scope of agile development activities, including requirements gathering, acceptance test driven development (ATDD), behavior driven development (BDD), test driven development (TDD), agile architecture and design, clean coding practices, continuous integration and agile development teamwork and collaboration. Students will build a small application from the ground up using ATDD and TDD practices and getting exposure to innovative tools such as Maven, Jenkins/Hudson, Subversion, JUnit, Mock Testing, Selenium, Spock, JBehave.

Automated testing techniques are covered in detail in this workshop. Indeed, learning how to write more effective tests is an excellent way to write better designed, more maintainable and more reliable code. The course covers fundamental TDD and BDD practices for Java Developers. Continuous Integration, or CI, is a cornerstone of modern software development best practices.

Topics Include:

  • Principles of Behavior Driven Development (BDD) and Agile Requirements:
    An introduction to the fundamental concepts and motivations behind Behavior-Driven Development and related techniques. BDD principles can be applied to requirements gathering and analysis activities. In this module, we learn how techniques such as Acceptance Test Driven Development, Executable Specifications and Feature Injection can significantly improve the quality, reliability and relevance of the application being built, and provide a much better traceability back to, and understanding of, the core business requirements. The course uses high-level BDD tools such as JBehave to build a working set of executable specifications from the ground up.
  • Agile Architecture
    Architecture is just as important in Agile projects as it is in conventional software projects. In this module we discuss the key principles of Agile architecture and design, including the role of architecture in Agile projects, when, how and by whom architecture is specified, implemented and validated.
  • Test Driven Development
    Test Driven Development (TDD) is a key Agile development practice, and is arguably the single most effective way to improve code quality and reliability. In this section, we focus on core TDD and BDD practices at the coding level, and learn how to effectively apply BDD practices in Java both by using advanced JUnit features and testing approaches such as Mock testing. Unit testing vs. Integration testing is covered. Web testing frameworks such as Selenium is introduced. Specific BDD libraries such as Spock are covered as well as topics such as good test design and organization and testing databases.
  • Refactoring and Clean Coding
    Refactoring is an essential part of maintaining high code quality and reducing maintenance costs. And a solid understanding of clean coding principles is vital to writing maintainable and understandable code. This course explores refactoring principles and patterns, and also discusses effective techniques to help make your code clean, readable and highly maintainable.
  • Team Programming and Collaboration
    Team collaboration and communication techniques are discussed along with source code control and version management systems. Subversion and distributed systems such as Git are covered.
  • Continuous Integration and Delivery
    This module covers how Continuous Integration and Delivery practices can be used to enhance team communication and accelerate feedback. Jenkins, an Open Source Continuous Integration tool, is by far the most popular . This course will teach you how to build a powerful and robust CI infrastructure using Maven and Jenkins and automating the build process with Jenkins and provide a wealth of best practices and real-world tips

Developing Hybrid Mobile Applications

26-28  Haziran ve 22-24 Temmuz tarihlerinde Eteration Academy olarak Developing Hybrid Mobile Applications konulu eğitimleri düzenlemekteyiz. Eğitim bilgilerine aşağıdan ulaşabilirsiniz:

Detaylı bilgi ve kayıt için


0212 328 08 25

Developing Hybrid Mobile Applications

Hybrid development combines the best (or worst) of both the native and HTML5 worlds. Hybrid apps primarily built using HTML5 and JavaScript, that is then wrapped inside a thin native container that provides access to native platform features. PhoneGap is an example of the most popular container for creating hybrid mobile apps and enabling native apis to be used from javascript.

For the most part, hybrid apps provide the best of both worlds. Existing web developers that have become gurus at optimizing JavaScript, pushing CSS to create beautiful layouts, and writing compliant HTML code that works on any platform can now create sophisticated mobile applications that don’t sacrifice the cool native capabilities. In certain circumstances, native developers can write plugins for tasks like image processing. Apps can package HTML and JavaScript code inside the mobile application binary, in a manner similar to the structure of a native application. In this scenario you use REST APIs to move data back and forth between the device and the cloud


Topics Include

  • Modelling Hybrid Mobile UI
  • Structure of Hybrid apps
  • Overview of Mobile Frameworks
  • HTML5, CSS3 and Javascript
  • PhoneGap/Apache Cordova
  • Development Setup
  • Best Mobile Design Practices
  • Useful Metatags
  • Working with Local Data
  • Working with Remote Data
  • Working With Media
  • Integration with Device APIs
  • Debugging
  • Offline Apps
  • Single Sourcing
  • Simple Security for Hybrid Mobile Applications

Android Developer Days is reloaded for 2013

Well-known names of Android Community will give speech about on various topics of Android on ADD 2013.

 Sponsors: Turkcell, Qualcomm, Blackberry, Paypal, Alcatel, İş Bank, Pozitron,  STM,  Netmera, Texas Instruments, ShiftDelete.net, Webrazzi, Tivilog, Btnet.com.tr, BThaber, Radio METU, indir.com, Pusula Publishing, Koza Publishing, Seçkin Publishing, paylas.com, PeakGames, METU Technopolis, Jetbrains 

Android Developer Days(ADD) will take   place on June 14/15, 2013 in METU Cultural and Convention Center, Ankara, Turkey. ADD 2013 is targeted to be the one of the biggest international tech related community organization in EMEA.  Event that a total of 60 speakers, 20 speakers coming from abroad. 1500 participants are expected for event. 

ADD is a technology conference which include seminars and competitions on the mobile world and Android technology. Well-known names of Android community such as, Lars Vogel, Eric Lafortune, Bernd Schulze, Mark Allison, will  give speeches on ADD. And here is the Android Developer Days schedule.  ADD is free of charge. Just register to the event.

ADD also host two sub events. Firstly, Ecahack Hackathon will be organized in the Android Developer Days.  Ecahack will start on 06/14/2013 at 13:30, and it will end on 15/06/2013 at 13:30 in METU CCC. Android developers will run 24 hours a day writing code. Turkcell will give various gifts to the winners of the competition.

Secondly, Innov-a-thon’Lite Turkey will be 3 hour idea marathon event.  Dubai based seed accelerator TURN8 will be on ADD for supports innovative ideas by seeding investment funding and business management. TURN8 (www.TURN8.co) is a seed accelerator program, a DP World initiative, powered by the i360Accelerator.

Lastly here is the ADD organizer list from7 countries: GDG Ankara, GDG İstanbul, ODTÜ IEEE, GDG Baku, GTUG Brussels, GDG Cluj-Napoca, GDG Dnipropetrovsk, GDG Eskişehir, GDG Konya, GDG Kyiv, GDG Lviv, GDG Samsun, GDG Tbilisi, GDG Timişoara, GDG Zürich, GDG Moldova


Infamous Java bugs and pitfalls

In year 2000, I was in university and was on the verge of picking a language to build my career on. Java was not yet the mainstream but highly popular and on the spots. Applets were (not yet broken) fancy, shiny when compared to static html pages. Swing was not a bad choice to build desktop apps. J2EE was rising and getting attention.

It has been 13 years since then and Java went mainstream although applets failed miserably, not really considered for desktop apps and J2EE was too complicated to even build simple stuff but still nothing stopped Java from being the most popular programming language.

It was no surprise, Java is beatiful, type safe and easy to learn language. There were many very good implemantation details in Java such the garbage collector, strings (finalized class), collections which offer great implemantations of merge and quicksort, built in hashcode methods and many more. However, still Java is far from being perfect and may introduce some unexpected behaviour.

The abs bug:
Well this is a very minor flaw but there is a probability that Math.abs() function may return negative value. Weird? actually simple, Java integers can get a value between -2,147,483,648 to 2,147,483,647 which clearly shows -2,147,483,648 can not be represented in positive.
So is this a bug? Well the expected value is positive so yes definitely but in the end this is actually an overflow. So how to fix it? One way would be checking Integer.MIN_VALUE before using abs function or using bit operators to manipulate negative sign instead.

Autoboxing the primitives pitfalls:
Autoboxing makes it easy to work with primitive types and their object counterpart. However moving between them may introduce some unexpected behavior. For example Integer i1=6 can not be compared to Integer i2=6 with == operator where int i3=6 can be compared to those with ==. However using equals may not work as expected too. For example Long x=0L; returns true when x.equals(0L) but returns false when x.equals(0). Weird? Not really since x is long where 0 (without L) is int. So those are not even same object types. Also using primitive types with collections may result unexpected behavior. Finally Autoboxing may result problems in overloading. Lets say we have Integer i=6 and call method sum(i); and we have two sum methods like; sum(long val) and sum(Long val). Which one do you think will be called? Again reasonable but not expected to see at first look and may lead problems in your app.

BigDecimal constructor bug:
If you haven’t already check Java Puzzlers from Joshua Bloch. If you create two Big decimals using double constructor (x1=new BigDecimal(2.00) and x2=new BigDecimal (1.10)) and use subtract (x1.subtract(x2)) you will end up with 0.8999999999. The double constructor of BigDecimal doesn’t work as expected and string constructor needs to be used instead (new BigDecimal(“2.00″)). This might be a serious problem since BigDecimal is widely used for money calculations!

System.out.println pitfall:
println() is one of the first functions that is tought to cs students. It is easy and used often. Usually quite ok to use when you are trying some logic or debugging some values. However System.out is synchronized so acquires a lock when accessed. So using println can cause your app to run in synchronized context which actually means threads will be blocked when accessing println. Imagine a webserver and an app logging with println and you will end up with thread locks and each request waiting for other. So println is ok and useful but not for real apps and logging!

Map bug:
Again take a look at Java Puzzlers from Joshua Bloch, the fifth puzzle(size matters) introduces a strange behavior between an HashMap and an EnumMap where with same values, one map has a size of 2 where the other is 1. Several Map implementations such as IdentityHashMap, EnumMap may introduce this behavior.
Is this a bug? Well certainly we expect same principles from map implementations but Bloch describes that as the spec was not clear at the time.

Cpu Number bug:
This may not be a huge problem unless you really rely on hardware. To get available processor count Java offers Runtime.getRuntime().availableProcessors() method which returns an int number as the number of the processors available. However you may end up getting unexpected numbers if you give a try. For example on my quad-core i7, I get 8. So this method does not return the number of hardware cpus nor the number of cores but the number of execution engines (virtual cores). In my case because quad-core i7s support hyper treading it actually acts like it has eight cores.
So is this a bug? Definitely not since the hardware and the OS acts as if they have that number of physical cpus but still be careful counting if you rely on solid hardware.

Generic arrays
In Java arrays are created as follows, int[] arr=new int[5]; so if you have a generic type of T, you would expect to create a generic array this way: T[]=new T[5]; but simply you can’t. Java does not allow generic array creation and this is actually because generics are implemented in Java using Erasure. Generics are implemented purely in compiler level and actually only one class file is generated for each class. So to create the array we need an ugly cast as follows, T[]=(T[]) new Object[5]; and when you try to compile, the compiler will issue a warning that you are doing an unsafe cast!
Of course this is not bug, it is just an implementation problem given for the sake of simplicity and compability when generics were implemented. But raising a compiler warning on a design issue may confuse someone who faced it for the first time.

So this is definitely not the end of the list but still Java offers a beatiful syntax, type safety and a realiable easy to learn language. And finally no language or implementation is perfect!