blob: 98820fb17da2b674766274ed6570059e8e2780ee [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>Apache Flink: Apache Flink Code Style and Quality Guide — Formatting</title>
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
<link rel="icon" href="/favicon.ico" type="image/x-icon">
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<link rel="stylesheet" href="/css/flink.css">
<link rel="stylesheet" href="/css/syntax.css">
<!-- Blog RSS feed -->
<link href="/blog/feed.xml" rel="alternate" type="application/rss+xml" title="Apache Flink Blog: RSS feed" />
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<!-- We need to load Jquery in the header for custom google analytics event tracking-->
<script src="/js/jquery.min.js"></script>
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<!-- Main content. -->
<div class="container">
<div class="row">
<div id="sidebar" class="col-sm-3">
<!-- Top navbar. -->
<nav class="navbar navbar-default">
<!-- The logo. -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<div class="navbar-logo">
<a href="/">
<img alt="Apache Flink" src="/img/flink-header-logo.svg" width="147px" height="73px">
</a>
</div>
</div><!-- /.navbar-header -->
<!-- The navigation links. -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-main">
<!-- First menu section explains visitors what Flink is -->
<!-- What is Stream Processing? -->
<!--
<li><a href="/streamprocessing1.html">What is Stream Processing?</a></li>
-->
<!-- What is Flink? -->
<li><a href="/flink-architecture.html">What is Apache Flink?</a></li>
<!-- What is Stateful Functions? -->
<li><a href="/stateful-functions.html">What is Stateful Functions?</a></li>
<!-- Use cases -->
<li><a href="/usecases.html">Use Cases</a></li>
<!-- Powered by -->
<li><a href="/poweredby.html">Powered By</a></li>
&nbsp;
<!-- Second menu section aims to support Flink users -->
<!-- Downloads -->
<li><a href="/downloads.html">Downloads</a></li>
<!-- Getting Started -->
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Getting Started<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="https://ci.apache.org/projects/flink/flink-docs-release-1.11/getting-started/index.html" target="_blank">With Flink <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<li><a href="https://ci.apache.org/projects/flink/flink-statefun-docs-release-2.1/getting-started/project-setup.html" target="_blank">With Flink Stateful Functions <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<li><a href="/training.html">Training Course</a></li>
</ul>
</li>
<!-- Documentation -->
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Documentation<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="https://ci.apache.org/projects/flink/flink-docs-release-1.11" target="_blank">Flink 1.11 (Latest stable release) <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<li><a href="https://ci.apache.org/projects/flink/flink-docs-master" target="_blank">Flink Master (Latest Snapshot) <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<li><a href="https://ci.apache.org/projects/flink/flink-statefun-docs-release-2.1" target="_blank">Flink Stateful Functions 2.1 (Latest stable release) <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<li><a href="https://ci.apache.org/projects/flink/flink-statefun-docs-master" target="_blank">Flink Stateful Functions Master (Latest Snapshot) <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
</ul>
</li>
<!-- getting help -->
<li><a href="/gettinghelp.html">Getting Help</a></li>
<!-- Blog -->
<li><a href="/blog/"><b>Flink Blog</b></a></li>
<!-- Flink-packages -->
<li>
<a href="https://flink-packages.org" target="_blank">flink-packages.org <small><span class="glyphicon glyphicon-new-window"></span></small></a>
</li>
&nbsp;
<!-- Third menu section aim to support community and contributors -->
<!-- Community -->
<li><a href="/community.html">Community &amp; Project Info</a></li>
<!-- Roadmap -->
<li><a href="/roadmap.html">Roadmap</a></li>
<!-- Contribute -->
<li><a href="/contributing/how-to-contribute.html">How to Contribute</a></li>
<ul class="nav navbar-nav navbar-subnav">
<li >
<a href="/contributing/contribute-code.html">Contribute Code</a>
</li>
<li >
<a href="/contributing/reviewing-prs.html">Review Pull Requests</a>
</li>
<li >
<a href="/contributing/code-style-and-quality-preamble.html">Code Style and Quality Guide</a>
</li>
<li >
<a href="/contributing/contribute-documentation.html">Contribute Documentation</a>
</li>
<li >
<a href="/contributing/docs-style.html">Documentation Style Guide</a>
</li>
<li >
<a href="/contributing/improve-website.html">Contribute to the Website</a>
</li>
</ul>
<!-- GitHub -->
<li>
<a href="https://github.com/apache/flink" target="_blank">Flink on GitHub <small><span class="glyphicon glyphicon-new-window"></span></small></a>
</li>
&nbsp;
<!-- Language Switcher -->
<li>
<a href="/zh/contributing/code-style-and-quality-formatting.html">中文版</a>
</li>
</ul>
<ul class="nav navbar-nav navbar-bottom">
<hr />
<!-- Twitter -->
<li><a href="https://twitter.com/apacheflink" target="_blank">@ApacheFlink <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<!-- Visualizer -->
<li class=" hidden-md hidden-sm"><a href="/visualizer/" target="_blank">Plan Visualizer <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<hr />
<li><a href="https://apache.org" target="_blank">Apache Software Foundation <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<li>
<style>
.smalllinks:link {
display: inline-block !important; background: none; padding-top: 0px; padding-bottom: 0px; padding-right: 0px; min-width: 75px;
}
</style>
<a class="smalllinks" href="https://www.apache.org/licenses/" target="_blank">License</a> <small><span class="glyphicon glyphicon-new-window"></span></small>
<a class="smalllinks" href="https://www.apache.org/security/" target="_blank">Security</a> <small><span class="glyphicon glyphicon-new-window"></span></small>
<a class="smalllinks" href="https://www.apache.org/foundation/sponsorship.html" target="_blank">Donate</a> <small><span class="glyphicon glyphicon-new-window"></span></small>
<a class="smalllinks" href="https://www.apache.org/foundation/thanks.html" target="_blank">Thanks</a> <small><span class="glyphicon glyphicon-new-window"></span></small>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</nav>
</div>
<div class="col-sm-9">
<div class="row-fluid">
<div class="col-sm-12">
<h1>Apache Flink Code Style and Quality Guide — Formatting</h1>
<ul class="list-group" style="padding-top: 30px; font-weight: bold;">
<li class="list-group-item">
<a href="/contributing/code-style-and-quality-preamble.html">
Preamble
</a>
</li>
<li class="list-group-item">
<a href="/contributing/code-style-and-quality-pull-requests.html">
Pull Requests &amp; Changes
</a>
</li>
<li class="list-group-item">
<a href="/contributing/code-style-and-quality-common.html">
Common Coding Guide
</a>
</li>
<li class="list-group-item">
<a href="/contributing/code-style-and-quality-java.html">
Java Language Guide
</a>
</li>
<li class="list-group-item">
<a href="/contributing/code-style-and-quality-scala.html">
Scala Language Guide
</a>
</li>
<li class="list-group-item">
<a href="/contributing/code-style-and-quality-components.html">
Component Guides
</a>
</li>
<li class="list-group-item">
<a href="/contributing/code-style-and-quality-formatting.html">
Formatting Guide
</a>
</li>
</ul>
<hr />
<div class="page-toc">
<ul id="markdown-toc">
<li><a href="#java-code-formatting-style" id="markdown-toc-java-code-formatting-style">Java Code Formatting Style</a> <ul>
<li><a href="#license" id="markdown-toc-license">License</a></li>
<li><a href="#imports" id="markdown-toc-imports">Imports</a></li>
<li><a href="#naming" id="markdown-toc-naming">Naming</a></li>
<li><a href="#whitespaces" id="markdown-toc-whitespaces">Whitespaces</a></li>
<li><a href="#breaking-the-lines-of-too-long-statements" id="markdown-toc-breaking-the-lines-of-too-long-statements">Breaking the lines of too long statements</a></li>
<li><a href="#braces" id="markdown-toc-braces">Braces</a></li>
<li><a href="#javadocs" id="markdown-toc-javadocs">Javadocs</a></li>
<li><a href="#modifiers" id="markdown-toc-modifiers">Modifiers</a></li>
<li><a href="#files" id="markdown-toc-files">Files</a></li>
<li><a href="#misc" id="markdown-toc-misc">Misc</a></li>
</ul>
</li>
</ul>
</div>
<h2 id="java-code-formatting-style">Java Code Formatting Style</h2>
<p>We recommend to set up the IDE to automatically check the code style. Please follow the <a href="https://ci.apache.org/projects/flink/flink-docs-master/flinkDev/ide_setup.html#checkstyle-for-java">IDE setup guide</a> for that.</p>
<h3 id="license">License</h3>
<ul>
<li><strong>Apache license headers.</strong> Make sure you have Apache License headers in your files. The RAT plugin is checking for that when you build the code.</li>
</ul>
<h3 id="imports">Imports</h3>
<ul>
<li><strong>Empty line before and after package declaration.</strong></li>
<li><strong>No unused imports.</strong></li>
<li><strong>No redundant imports.</strong></li>
<li><strong>No wildcard imports.</strong> They can cause problems when adding to the code and in some cases even during refactoring.</li>
<li><strong>Import order.</strong> Imports must be ordered alphabetically, grouped into the following blocks, with each block separated by an empty line:
<ul>
<li>&lt;imports from org.apache.flink.*&gt;</li>
<li>&lt;imports from org.apache.flink.shaded.*&gt;</li>
<li>&lt;imports from other libraries&gt;</li>
<li>&lt;imports from javax.*&gt;</li>
<li>&lt;imports from java.*&gt;</li>
<li>&lt;imports from scala.*&gt;</li>
<li>&lt;static imports&gt;</li>
</ul>
</li>
</ul>
<h3 id="naming">Naming</h3>
<ul>
<li><strong>Package names must start with a letter, and must not contain upper-case letters or special characters.</strong>
<strong>Non-private static final fields must be upper-case, with words being separated by underscores.</strong>(<code>MY_STATIC_VARIABLE</code>)</li>
<li><strong>Non-static fields/methods must be in lower camel case.</strong> (<code>myNonStaticField</code>)</li>
</ul>
<h3 id="whitespaces">Whitespaces</h3>
<ul>
<li><strong>Tabs vs. spaces.</strong> We are using tabs for indentation, not spaces.
We are aware that spaces are a bit nicer; it just happened to be that we started with tabs a long time ago (because Eclipse’s default style used tabs then), and we tried to keep the code base homogeneous (not mix tabs and spaces).</li>
<li><strong>No trailing whitespace.</strong></li>
<li><strong>Spaces around operators/keywords.</strong> Operators (<code>+</code>, <code>=</code>, <code>&gt;</code>, …) and keywords (<code>if</code>, <code>for</code>, <code>catch</code>, …) must have a space before and after them, provided they are not at the start or end of the line.</li>
</ul>
<h3 id="breaking-the-lines-of-too-long-statements">Breaking the lines of too long statements</h3>
<p>In general long lines should be avoided for the better readability. Try to use short statements which operate on the same level of abstraction. Break the long statements by creating more local variables, defining helper functions etc.</p>
<p>Two major sources of long lines are:</p>
<ul>
<li><strong>Long list of arguments</strong> in function declaration or call: <code>void func(type1 arg1, type2 arg2, ...)</code></li>
<li><strong>Long sequence of chained calls</strong>: <code>list.stream().map(...).reduce(...).collect(...)...</code></li>
</ul>
<p>Rules about breaking the long lines:</p>
<ul>
<li>Break the argument list or chain of calls if the line exceeds limit or earlier if you believe that the breaking would improve the code readability</li>
<li>If you break the line then each argument/call should have a separate line, including the first one</li>
<li>Each new line should have one extra indentation (or two for a function declaration) relative to the line of the parent function name or the called entity</li>
</ul>
<p>Additionally for function arguments:</p>
<ul>
<li>The opening parenthesis always stays on the line of the parent function name</li>
<li>The possible thrown exception list is never broken and stays on the same last line, even if the line length exceeds its limit</li>
<li>The line of the function argument should end with a comma staying on the same line except the last argument</li>
</ul>
<p>Example of breaking the list of function arguments:</p>
<div class="highlight"><pre><code>public void func(
int arg1,
int arg2,
...) throws E1, E2, E3 {
}
</code></pre></div>
<p>The dot of a chained call is always on the line of that chained call proceeding the call at the beginning.</p>
<p>Example of breaking the list of chained calls:</p>
<div class="highlight"><pre><code>values
.stream()
.map(...)
.collect(...);
</code></pre></div>
<h3 id="braces">Braces</h3>
<ul>
<li><strong>Left curly braces (<code>{</code>) must not be placed on a new line.</strong></li>
<li><strong>Right curly braces (<code>}</code>) must always be placed at the beginning of the line.</strong></li>
<li><strong>Blocks.</strong> All statements after <code>if</code>, <code>for</code>, <code>while</code>, <code>do</code>, … must always be encapsulated in a block with curly braces (even if the block contains one statement).</li>
</ul>
<h3 id="javadocs">Javadocs</h3>
<ul>
<li><strong>All public/protected methods and classes must have a Javadoc.</strong></li>
<li><strong>The first sentence of the Javadoc must end with a period.</strong></li>
<li><strong>Paragraphs must be separated with a new line, and started with &lt;p&gt;.</strong></li>
</ul>
<h3 id="modifiers">Modifiers</h3>
<ul>
<li><strong>No redundant modifiers.</strong> For example, public modifiers in interface methods.</li>
<li><strong>Follow JLS3 modifier order.</strong> Modifiers must be ordered in the following order: public, protected, private, abstract, static, final, transient, volatile, synchronized, native, strictfp.</li>
</ul>
<h3 id="files">Files</h3>
<ul>
<li><strong>All files must end with <code>\n</code>.</strong></li>
<li><strong>File length must not exceed 3000 lines.</strong></li>
</ul>
<h3 id="misc">Misc</h3>
<ul>
<li><strong>Arrays must be defined Java-style.</strong> For example, <code>public String[] array</code>.</li>
<li><strong>Use Flink Preconditions.</strong> To increase homogeneity, consistently use the <code>org.apache.flink.Preconditions</code> methods <code>checkNotNull</code> and <code>checkArgument</code> rather than Apache Commons Validate or Google Guava.</li>
</ul>
<hr />
</div>
</div>
</div>
</div>
<hr />
<div class="row">
<div class="footer text-center col-sm-12">
<p>Copyright © 2014-2019 <a href="http://apache.org">The Apache Software Foundation</a>. All Rights Reserved.</p>
<p>Apache Flink, Flink®, Apache®, the squirrel logo, and the Apache feather logo are either registered trademarks or trademarks of The Apache Software Foundation.</p>
<p><a href="/privacy-policy.html">Privacy Policy</a> &middot; <a href="/blog/feed.xml">RSS feed</a></p>
</div>
</div>
</div><!-- /.container -->
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.matchHeight/0.7.0/jquery.matchHeight-min.js"></script>
<script src="/js/codetabs.js"></script>
<script src="/js/stickysidebar.js"></script>
<!-- Google Analytics -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-52545728-1', 'auto');
ga('send', 'pageview');
</script>
</body>
</html>