blob: 6e33c26953d315c65d7794814071dc76e6833b94 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 1.5.7.1">
<title>N4JS and Java</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- ************* Meta ************* -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
<!-- ************* OpenGraph ************-->
<meta name="description" content="The Eclipse N4JS language and its IDE enable high-quality JavaScript development for large Node.js projects.">
<meta property="og:site_name" content="Eclipse N4JS"/>
<meta property="og:title" content="Eclipse N4JS Language and IDE"/>
<meta property="og:url" content="https://numberfour.github.io/n4js"/>
<meta property="og:description" content="The Eclipse N4JS language and its IDE enable high-quality JavaScript development for large Node.js projects."/>
<meta property="og:image" content="../images/n4js.png">
<!-- ************* Favicon ************-->
<link rel="icon" href="../images/favicon.ico" />
<link rel="icon" type="image/png" href="../images/favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="../images/favicon-16x16.png" sizes="16x16" />
<!-- ************* Back-to-top JQuery ************* -->
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>
<!-- ************* Prism.js Syntax Highlighter ******-->
<link href="../styles/prism.min.css" rel="stylesheet"/>
<script src="../scripts/prism.js"></script>
<!-- ************* Styles ************* -->
<link rel="stylesheet" type="text/css" href="../styles/n4js-adoc.css">
<!-- ****************** NavBar ****************** -->
<div id="menubar">
<div class="banner">
<a href="../index.html"><img id="logo" src="../images/n4js-logo.png" alt="N4JS Language and IDE"></a>
</div>
<ul>
<li><a href="../downloads.html"></i>Download</a></li>
<li><a href="../community.html"></i>Community</a></li>
<li><a href="../userguides/index.html">Documentation</a></li>
</ul>
</div>
<button id="tocbutton">TOC</button>
<div id=faq>
<nav>
<h2>FAQ</h2>
<ul>
<li><a href="index.html" >FAQ</a></li>
<li><a href="comparison-java.html" class="is-active">N4JS and Java</a></li>
<li><a href="comparison-typescript.html" >N4JS and Typescript</a></li>
</ul>
</nav>
</div>
</head>
<body class="book">
<div id="header">
</div>
<div id="content">
<h1 id="_n4js_and_java" class="sect0"><a class="link" href="#_n4js_and_java">N4JS and Java</a></h1>
<div class="sect1">
<h2 id="_introduction"><a class="link" href="#_introduction">Introduction</a></h2>
<div class="sectionbody">
<div class="paragraph">
<div class="title">N4JS and Java</div>
<p>N4JS is an extension of ECMAScript. It is therefore as different from Java as ECMAScript is. There are additional features which
are quite similar to Java, actually making ECMAScript feel more like <strong>Java</strong>Script. In the following, we describe the most
important similarities and differences of Java and N4JS.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_similarities"><a class="link" href="#_similarities">Similarities</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>The general idea of N4JS is to make ECMAScript as type safe as Java. For that reason, N4JS adds a static type system to ECMAScript.
Many concepts of this type system are similar to Java&#8217;s type system.</p>
</div>
<div class="sect2">
<h3 id="_nominal_typing"><a class="link" href="#_nominal_typing">Nominal Typing</a></h3>
<div class="paragraph">
<p>N4JS supports both, <a href="../features/nominal-and-structural-typing.html#nominal_and_structural_typing">nominal and structural typing</a>. Java has a nominal
type system and this is also the default mode in N4JS. When you just use a simple type reference, nominal typing (as in Java) is applied.</p>
</div>
<div class="paragraph">
<p>The following example should be easily understood by Java developers:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">class A { public foo(): void {} }
class B extends A {}
class C { public foo(): void {} }
function f(p: A) {}
f(new B());
f(new C()); // error: C is not a subtype of A.</code></pre>
</div>
</div>
<div class="paragraph">
<p>This example will produce an error in the last line because <code>C</code> is not a nominal subtype of <code>A</code>.</p>
</div>
<div class="paragraph">
<p>Overriding of members in N4JS is quite similar to Java although N4JS allows for slightly more flexibility due to the underlying
ECMAScript semantics (see <a href="#_function_subtyping">Function Subtyping</a>).</p>
</div>
</div>
<div class="sect2">
<h3 id="_generics"><a class="link" href="#_generics">Generics</a></h3>
<div class="paragraph">
<p>The most important concept (taken more or less 1:1 from Java) is generics. There are a lot of languages providing support for
generics. Often there is limited support compared to Java, or different concepts are used. There are languages, for example,
which support generic types but not generic functions, or do not support wildcards. Languages such as Scala, for instance, have
different concepts for generics.</p>
</div>
<div class="paragraph">
<p>N4JS provides all features related to generics as Java does. Supported are:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>generic types and generic methods (and functions)</p>
</li>
<li>
<p>type variables with lower bounds</p>
</li>
<li>
<p>parameterization with wildcards (and upper and lower bounds)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>N4JS even uses the very same <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-18.html">algorithm to infer type
variables as Java 8</a>. This algorithm is, of course, slightly adapted to support extra features of N4JS such as union types.</p>
</div>
<div class="paragraph">
<p>As a consequence, generics and parameterization should immediately be understood by Java programmers (as far as 'immediately
understood' can be applied to generics).</p>
</div>
<div class="paragraph">
<p>At the moment, the N4JS type system has some known issues when substituting type variables and instantiating wildcard
expressions. For the latter, Java uses a technique called "capture conversion" while N4JS implements a slightly simpler
one called "existential types". Future releases of N4JS will fix these issues.</p>
</div>
</div>
<div class="sect2">
<h3 id="_interfaces_and_abstract_declarations"><a class="link" href="#_interfaces_and_abstract_declarations">Interfaces and Abstract Declarations</a></h3>
<div class="paragraph">
<p>ECMAScript 2015 introduces classes similar to Java. In both languages, single inheritance is used. Although this simplifies
many scenarios, the limitations of single inheritance are often problematic. In Java, many of these problematic cases can
be solved with interfaces. N4JS also provides the concept of interfaces, allowing for classes to implement multiple interfaces.
Interfaces in N4JS allow for the definition of default methods as in Java 8, therefore overcoming most of the problems
introduced by single inheritance. Related to interfaces are abstract methods and, consequently, abstract classes which are
also supported in N4JS similarly to Java.</p>
</div>
<div class="paragraph">
<p>N4JS adapts the <code>instanceof</code> operator so it can be used in combination with interfaces at runtime.</p>
</div>
</div>
<div class="sect2">
<h3 id="_access_modifiers"><a class="link" href="#_access_modifiers">Access Modifiers</a></h3>
<div class="paragraph">
<p>When designing larger systems and frameworks, limiting access to certain elements is important for maintainability. Similar
to Java, N4JS introduces access modifiers to limit visibility of types and members. The following table shows the access
modifiers of N4JS compared to Java:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-center valign-top"><p class="tableblock"><strong>Java</strong></p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock"><strong>N4JS</strong></p></td>
<td class="tableblock halign-left valign-top" colspan="2"><p class="tableblock"><strong>Remark</strong></p></td>
</tr>
<tr>
<td class="tableblock halign-center valign-top" colspan="2"><p class="tableblock">Public</p></td>
<td class="tableblock halign-left valign-top" colspan="2"><p class="tableblock">Types and members, similar semantic</p></td>
</tr>
<tr>
<td class="tableblock halign-center valign-top" colspan="2"><p class="tableblock">Protected</p></td>
<td class="tableblock halign-left valign-top" colspan="2"><p class="tableblock">Members only, similar semantic</p></td>
</tr>
<tr>
<td class="tableblock halign-center valign-top"><p class="tableblock">Package</p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock">Project</p></td>
<td class="tableblock halign-left valign-top" colspan="2"><p class="tableblock">See below</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>While it is possible to organize modules in folders which could be interpreted as packages, N4JS does not really support the
notion of packages. Instead, it uses projects to encapsulate coherent functionality. Project is the default visibility in
N4JS as package is in Java. The semantics are also similar in both cases: elements (types or members) can only be accessed
from the same container (project in N4JS and package in Java).</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_differences"><a class="link" href="#_differences">Differences</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_auto_boxing"><a class="link" href="#_auto_boxing">Auto-Boxing</a></h3>
<div class="paragraph">
<p>In Java, primitive types can be auto-boxed to their corresponding object types (and vice versa). This is also true for
ECMAScript but there are subtle differences which might lead to misconceptions as shown in the following example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-n4js" data-lang="n4js">let bool: boolean = false;
let Bool: Boolean = new Boolean( false );
console.log( bool.valueOf(), bool ? "true" : "false");
console.log( Bool.valueOf(), Bool ? "true" : "false");</code></pre>
</div>
</div>
<div class="paragraph">
<p>Probably surprising for Java programmers, this would print out</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-n4js" data-lang="n4js">false 'false'
false 'true'</code></pre>
</div>
</div>
<div class="paragraph">
<p>In order avoid these problems, N4JS does not support auto-boxing. Instead, primitives and object types have to be
explicitly converted using either the <code>constructor</code>, <code>Object.valueof</code> or other related methods.</p>
</div>
</div>
<div class="sect2">
<h3 id="_function_subtyping"><a class="link" href="#_function_subtyping">Function Subtyping</a></h3>
<div class="paragraph">
<p>Function (or method) subtyping comes into play in two cases: method overriding and passing functions as arguments
(callbacks, for example). In both cases, the type checker has to ensure that a function <code><strong>f</strong></code> is compatible with
another function <code><strong>f'</strong></code> (in other words, that the type of <code><strong>f</strong></code> is a subtype of the type of <code><strong>f'</strong></code>). In Java this is called
"override compatible".</p>
</div>
<div class="paragraph">
<p>In Java, a method <code><strong>f</strong></code> is override compatible to a <code><strong>f'</strong></code> if and only if</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>it has the same name</p>
</li>
<li>
<p>it has the same number of parameters</p>
</li>
<li>
<p>the type of each parameter of <code><strong>f</strong></code> must be a supertype of the corresponding parameter of <code><strong>f'</strong></code></p>
</li>
<li>
<p>its return type is a subtype of the return type of <code><strong>f'</strong></code></p>
</li>
</ol>
</div>
<div class="paragraph">
<p>In ECMAScript, it is possible to call a function of a method with more or less arguments than declared
formal parameters. Calling a function with less arguments is not allowed in N4JS (unless the parameters
are declared as optional). The definition of "override compatible" is, therefore, a little bit different
in N4JS.</p>
</div>
<div class="paragraph">
<p>In N4JS,<code><strong>f'</strong></code> is override comptabible to <code><strong>f</strong></code> (or its type is a subtype of the type of <code><strong>f</strong></code>), if</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>it has the same name (in case of method override)</p>
</li>
<li>
<p>it has the same number or less of parameters, or superfluous parameters are optional</p>
</li>
<li>
<p>the type of each parameter of <code><strong>f'</strong></code> must be a subtype of the corresponding parameter of <code><strong>f</strong></code></p>
</li>
<li>
<p>its return type is a subtype of the return type of <code><strong>f</strong></code> , or <code><strong>f</strong></code> has no return type (it&#8217;s void).</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>For example, the following code is correct in N4JS while it would cause compile errors in Java:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-n4js" data-lang="n4js">class A {
foo(s: string): void {}
}
class B extends A {
@Override
foo(): number { return 0 }
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_overloading"><a class="link" href="#_overloading">Overloading</a></h3>
<div class="paragraph">
<p>There is no method overloading in ECMAScript and therefore there cannot be overloading in N4JS. In order to 'emulate'
overloading to a certain degree, union types and optional parameters can be used.</p>
</div>
</div>
<div class="sect2">
<h3 id="_static_members"><a class="link" href="#_static_members">Static Members</a></h3>
<div class="paragraph">
<p>In Java, a static member of a class can be accessed either</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>via the declaring class (or a subclass)</p>
</li>
<li>
<p>via an instance</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>In N4JS, a static member can only be called via the declaring class.</p>
</div>
<div class="paragraph">
<p>Note that the <code>this</code> literal is bound to the class (to the constructor function, in fact). This enables
static polymorphism as shown in the next example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-n4js" data-lang="n4js">class A {
public static s() { console.log("A.s"); this.t(); };
public static t() { console.log("A.t"); };
}
class B extends A {
@Override
public static t() { console.log("B.t"); };
}
A.s();
B.s();</code></pre>
</div>
</div>
<div class="paragraph">
<p>This will print out</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>A.s
A.t
A.s
B.t</code></pre>
</div>
</div>
<div class="paragraph">
<p>The last line in particular may be surprising for Java programmers.</p>
</div>
</div>
</div>
</div>
</div>
<div id="footer">
<div id="footer-text">
</div>
</div>
<div class="Grid social" style="color:#d5dfea">
<div class="Cell Cell--2-12 m-Cell--withMargin">
<h2>Quick Links</h2>
<ul>
<li><a href="../downloads.html">Download</a></li>
<li><a href="../userguides/index.html">Documentation</a></li>
<li><a href="https://github.com/eclipse/n4js/">Source</a></li>
<li><a href="https://github.com/eclipse/n4js/issues">Issues</a></li>
</ul>
</div>
<div class="Cell Cell--2-12 m-Cell--withMargin">
<br/><br/>
<ul>
<li><a href="https://www.eclipse.org/forums/index.php/f/365/">Forum</a></li>
<li><a href="http://n4js.blogspot.de/">Blog</a></li>
<li><a href="https://dev.eclipse.org/mailman/listinfo/n4js-dev">Mailing List</a></li>
<li><a href="https://projects.eclipse.org/projects/technology.n4js">Eclipse Project Page</a></li>
<li><a href="https://twitter.com/n4jsdev">Tweets by n4jsdev</a></li>
</ul>
</div>
<div class="Cell Cell--2-12 m-Cell--withMargin">
<br/><br/>
<ul>
<li><a href="http://www.eclipse.org/">Eclipse Home</a></li>
<li><a href="http://www.eclipse.org/legal/privacy.php">Privacy Policy</a></li>
<li><a href="http://www.eclipse.org/legal/termsofuse.php">Terms of Use</a></li>
<li><a href="http://www.eclipse.org/legal/copyright.php">Copyright Agent</a></li>
<li><a href="http://www.eclipse.org/legal/">Legal</a></li>
</ul>
</div>
<div style="clear: both; height: 0; overflow: hidden;"></div>
</div>
<script>
// Toggle the table of contents
$( "button#tocbutton" ).click(function() {
if ($("#tocbutton").css('right') == '25px') {
$( "#tocbutton" ).animate({right: '215px'},"slow");
$( "#toc.toc2" ).animate({right: '0'},"slow");
}
else {
$( "#tocbutton" ).animate({right: '25px'},"slow");
$( "#toc.toc2" ).animate({right: '-13rem'},"slow");
}
});
</script>
<script type="text/javascript">
// Create a back to top button
$('body').prepend('<a href="#" class="back-to-top">Back to Top</a>');
var amountScrolled = 300;
$(window).scroll(function() {
if ( $(window).scrollTop() > amountScrolled ) {
$('a.back-to-top').fadeIn('slow');
} else {
$('a.back-to-top').fadeOut('slow');
}
});
$('a.back-to-top, a.simple-back-to-top').click(function() {
$('html, body').animate({
scrollTop: 0
}, 700);
return false;
});
</script>
</body>
</html>