diff --git a/java/java-impl/src/com/intellij/codeInsight/FunctionalInterfaceSuggester.java b/java/java-impl/src/com/intellij/codeInsight/FunctionalInterfaceSuggester.java
index e2fd08ac64a1..b869379d111a 100644
--- a/java/java-impl/src/com/intellij/codeInsight/FunctionalInterfaceSuggester.java
+++ b/java/java-impl/src/com/intellij/codeInsight/FunctionalInterfaceSuggester.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.AnnotatedMembersSearch;
+import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.NullableFunction;
@@ -87,6 +88,21 @@ public class FunctionalInterfaceSuggester {
return null;
}
+ final PsiClassType[] interfaceThrownTypes = interfaceMethod.getThrowsList().getReferencedTypes();
+ final PsiClassType[] thrownTypes = method.getThrowsList().getReferencedTypes();
+ for (PsiClassType thrownType : thrownTypes) {
+ if (!ExceptionUtil.isHandledBy(thrownType, interfaceThrownTypes, substitutor)) {
+ return null;
+ }
+ }
+
+ for (PsiClassType thrownType : interfaceThrownTypes) {
+ final PsiCodeBlock codeBlock = PsiTreeUtil.getContextOfType(method, PsiCodeBlock.class);
+ if (codeBlock == null || !ExceptionUtil.isHandled(thrownType, codeBlock)) {
+ return null;
+ }
+ }
+
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(aClass.getProject());
final PsiType type = elementFactory.createType(aClass, substitutor);
return type;
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java
index fe04b0211b7f..e7b391c7894c 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java
@@ -541,7 +541,9 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase {
if (!processor.prepare()) return false;
processor.showDialog();
- final PsiMethod emptyMethod = processor.generateEmptyMethod("name");
+ //provide context for generated method to check exceptions compatibility
+ final PsiMethod emptyMethod = JavaPsiFacade.getElementFactory(project)
+ .createMethodFromText(processor.generateEmptyMethod("name").getText(), elements[0]);
final Collection extends PsiType> types = FunctionalInterfaceSuggester.suggestFunctionalInterfaces(emptyMethod);
if (types.isEmpty()) {
return false;
diff --git a/java/java-tests/testData/refactoring/introduceFunctionalParameter/afterExceptionPreventFromCompatibility.java b/java/java-tests/testData/refactoring/introduceFunctionalParameter/afterExceptionPreventFromCompatibility.java
new file mode 100644
index 000000000000..b5cee16b01e9
--- /dev/null
+++ b/java/java-tests/testData/refactoring/introduceFunctionalParameter/afterExceptionPreventFromCompatibility.java
@@ -0,0 +1,19 @@
+class Test {
+ @FunctionalInterface
+ interface I {
+ void f() throws Exception;
+ }
+
+ void bar() {
+ foo(new Runnable() {
+ public void run() {
+ System.out.println("");
+ System.out.println("");
+ }
+ });
+ }
+
+ void foo(Runnable anObject) {
+ anObject.run();
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/introduceFunctionalParameter/afterThrownExceptionsAgree.java b/java/java-tests/testData/refactoring/introduceFunctionalParameter/afterThrownExceptionsAgree.java
new file mode 100644
index 000000000000..16d090f09aec
--- /dev/null
+++ b/java/java-tests/testData/refactoring/introduceFunctionalParameter/afterThrownExceptionsAgree.java
@@ -0,0 +1,19 @@
+class Test {
+ @FunctionalInterface
+ interface I {
+ void f() throws Exception;
+ }
+
+ void bar() throws Exception {
+ foo(new I() {
+ public void f() {
+ System.out.println("");
+ System.out.println("");
+ }
+ });
+ }
+
+ void foo(I anObject) throws Exception {
+ anObject.f();
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/introduceFunctionalParameter/beforeExceptionPreventFromCompatibility.java b/java/java-tests/testData/refactoring/introduceFunctionalParameter/beforeExceptionPreventFromCompatibility.java
new file mode 100644
index 000000000000..864989ae86fa
--- /dev/null
+++ b/java/java-tests/testData/refactoring/introduceFunctionalParameter/beforeExceptionPreventFromCompatibility.java
@@ -0,0 +1,15 @@
+class Test {
+ @FunctionalInterface
+ interface I {
+ void f() throws Exception;
+ }
+
+ void bar() {
+ foo();
+ }
+
+ void foo() {
+ System.out.println("");
+ System.out.println("");
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/introduceFunctionalParameter/beforeThrownExceptionsAgree.java b/java/java-tests/testData/refactoring/introduceFunctionalParameter/beforeThrownExceptionsAgree.java
new file mode 100644
index 000000000000..9a9175c8c695
--- /dev/null
+++ b/java/java-tests/testData/refactoring/introduceFunctionalParameter/beforeThrownExceptionsAgree.java
@@ -0,0 +1,15 @@
+class Test {
+ @FunctionalInterface
+ interface I {
+ void f() throws Exception;
+ }
+
+ void bar() throws Exception {
+ foo();
+ }
+
+ void foo() throws Exception {
+ System.out.println("");
+ System.out.println("");
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceFunctionalParameterTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceFunctionalParameterTest.java
index 6da97834656b..1bd71cfb4196 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceFunctionalParameterTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceFunctionalParameterTest.java
@@ -41,6 +41,14 @@ public class IntroduceFunctionalParameterTest extends LightRefactoringTestCase
doTest();
}
+ public void testExceptionPreventFromCompatibility() throws Exception {
+ doTest();
+ }
+
+ public void testThrownExceptionsAgree() throws Exception {
+ doTest();
+ }
+
@NotNull
@Override
protected String getTestDataPath() {