add lint unnecessary_nullable_for_final_variable_declarations
diff --git a/example/all.yaml b/example/all.yaml
index 3655b01..d68d3bf 100644
--- a/example/all.yaml
+++ b/example/all.yaml
@@ -151,6 +151,7 @@
     - unnecessary_getters_setters
     - unnecessary_lambdas
     - unnecessary_new
+    - unnecessary_nullable_for_final_variable_declarations
     - unnecessary_null_aware_assignments
     - unnecessary_null_in_if_null_operators
     - unnecessary_overrides
diff --git a/lib/src/rules.dart b/lib/src/rules.dart
index 61e7688..6f46a52 100644
--- a/lib/src/rules.dart
+++ b/lib/src/rules.dart
@@ -156,6 +156,7 @@
 import 'rules/unnecessary_new.dart';
 import 'rules/unnecessary_null_aware_assignments.dart';
 import 'rules/unnecessary_null_in_if_null_operators.dart';
+import 'rules/unnecessary_nullable_for_final_variable_declarations.dart';
 import 'rules/unnecessary_overrides.dart';
 import 'rules/unnecessary_parenthesis.dart';
 import 'rules/unnecessary_raw_strings.dart';
@@ -336,6 +337,7 @@
     //..register(UnnecessaryGetters())
     ..register(UnnecessaryGettersSetters())
     ..register(UnnecessaryLambdas())
+    ..register(UnnecessaryNullableForFinalVariableDeclarations())
     ..register(UnnecessaryOverrides())
     ..register(UnnecessaryParenthesis())
     ..register(UnnecessaryRawStrings())
diff --git a/lib/src/rules/unnecessary_nullable_for_final_variable_declarations.dart b/lib/src/rules/unnecessary_nullable_for_final_variable_declarations.dart
new file mode 100644
index 0000000..61a5f67
--- /dev/null
+++ b/lib/src/rules/unnecessary_nullable_for_final_variable_declarations.dart
@@ -0,0 +1,108 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+
+import '../analyzer.dart';
+
+const _desc = r'Use non-nullable type '
+    'for final variable initialized with non-nullable value.';
+
+const _details = r'''
+
+Use non-nullable type for final variable initialized with non-nullable value.
+
+**BAD:**
+```
+final int? i = 1;
+```
+
+**GOOD:**
+```
+final int i = 1;
+```
+
+''';
+
+class UnnecessaryNullableForFinalVariableDeclarations extends LintRule
+    implements NodeLintRule {
+  UnnecessaryNullableForFinalVariableDeclarations()
+      : super(
+            name: 'unnecessary_nullable_for_final_variable_declarations',
+            description: _desc,
+            details: _details,
+            maturity: Maturity.experimental,
+            group: Group.style);
+
+  @override
+  void registerNodeProcessors(NodeLintRegistry registry,
+      [LinterContext context]) {
+    final visitor = _Visitor(this, context);
+    registry.addCompilationUnit(this, visitor);
+    registry.addFieldDeclaration(this, visitor);
+    registry.addTopLevelVariableDeclaration(this, visitor);
+    registry.addVariableDeclarationStatement(this, visitor);
+  }
+}
+
+class _Visitor extends SimpleAstVisitor<void> {
+  _Visitor(this.rule, this.context);
+
+  final LintRule rule;
+  final LinterContext context;
+
+  bool _isNonNullableEnabled;
+
+  @override
+  void visitCompilationUnit(CompilationUnit node) {
+    _isNonNullableEnabled = node.featureSet.isEnabled(Feature.non_nullable);
+  }
+
+  @override
+  void visitFieldDeclaration(FieldDeclaration node) {
+    if (!_isNonNullableEnabled) return;
+
+    for (var variable in node.fields.variables) {
+      // We could also include public members in private classes but to do that
+      // we'd need to ensure that there are no instances of either the
+      // enclosing class or any subclass of the enclosing class that are ever
+      // accessible outside this library.
+      if (Identifier.isPrivateName(variable.name.name) || node.isStatic) {
+        _visit(variable);
+      }
+    }
+  }
+
+  @override
+  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    if (!_isNonNullableEnabled) return;
+
+    node.variables.variables.forEach(_visit);
+  }
+
+  @override
+  void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+    if (!_isNonNullableEnabled) return;
+
+    node.variables.variables.forEach(_visit);
+  }
+
+  void _visit(VariableDeclaration variable) {
+    if (!variable.isFinal && !variable.isConst) {
+      return;
+    }
+    if (variable.isSynthetic) {
+      return;
+    }
+    if (variable.initializer == null) {
+      return;
+    }
+    if (context.typeSystem.isNullable(variable.declaredElement.type) &&
+        context.typeSystem.isNonNullable(variable.initializer.staticType)) {
+      rule.reportLint(variable);
+    }
+  }
+}
diff --git a/test/rules/experiments/nnbd/rules/unnecessary_nullable_for_final_variable_declarations.dart b/test/rules/experiments/nnbd/rules/unnecessary_nullable_for_final_variable_declarations.dart
new file mode 100644
index 0000000..7ead35b
--- /dev/null
+++ b/test/rules/experiments/nnbd/rules/unnecessary_nullable_for_final_variable_declarations.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// test w/ `pub run test -N unnecessary_nullable_for_final_variable_declarations`
+
+final int? _i = 1; // LINT
+final int _j = 1; // OK
+final int? i = 1; // LINT
+final int j = 1; // OK
+const int? i = 1; // LINT
+const int j = 1; // OK
+
+class A {
+  final int? _i = 1; // LINT
+  final int _j = 1; // OK
+  final int? i = 1; // OK (may be overriden or may override)
+  final int j = 1; // OK
+  static final int? si = 1; // LINT
+  static final int sj = 1; // OK
+}
+
+extension E on A {
+  static final int? _e1i = 1; // LINT
+  static final int _e1j = 1; // OK
+  static final int? e1i = 1; // LINT
+  static final int e1j = 1; // OK
+}
+
+m() {
+  final int? _i = 1; // LINT
+  final int _j = 1; // OK
+  final int? i = 1; // LINT
+  final int j = 1; // OK
+}
diff --git a/test/rules/unnecessary_nullable_for_final_variable_declarations.dart b/test/rules/unnecessary_nullable_for_final_variable_declarations.dart
new file mode 100644
index 0000000..65718b8
--- /dev/null
+++ b/test/rules/unnecessary_nullable_for_final_variable_declarations.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// test w/ `pub run test -N unnecessary_nullable_for_final_variable_declarations`
+
+final int _i = 1; // OK