Follow the best practices
Stay organized with collections
Save and categorize content based on your preferences.
While working with keep rules, it's important to reach the right amount of
specificity to make sure you see benefits while maintaining your app's
behaviour. See the following sections to learn about good patterns as well as
things to avoid in keep rules.
Good patterns in keep rules
Well-defined keep rules are as specific as possible:
For the class specification, always specify a specific class, base class, or
annotated class if possible, as shown in the following examples:
-keepclassmembers class com.example.MyClass {
void someSpecificMethod();
}
-keepclassmembers ** extends com.example.MyBaseClass {
void someSpecificMethod();
}
-keepclassmembers @com.example.MyAnnotation class ** {
void someSpecificMethod();
}
Whenever possible, the member specification should be declared, and only
reference the parts of the class that must be kept for the app to function.
It's recommended to not apply a rule to an entire class by defining the
optional member scope as { *; }
unless strictly needed.
-keepclassmembers com.example.MyClass {
void someSpecificMethod();
void @com.example.MyAnnotation *;
}
If you can't adhere to these guidelines, you can temporarily isolate the code
that needs to be kept in a dedicated package and apply your keep rule to the
package. However, this isn't a solution for the long term. To learn more, see
Adopt optimizations incrementally. To use a keep rule for a package define
a keep rule as shown in the following example:
-keepclassmembers class com.example.pkg.** { *; }
Things to avoid
The keep rule syntax has many options, but for measurable sustainable
performance benefits we recommend not using the following:
- Avoid using the inversion operator
!
in keep rules because you could
unintentionally apply a rule to almost every class in your application.
- Don't use package-wide keep rules such as
-keep class com.example.pkg.** {
*; }
long-term. They can be used temporarily to work around issues when
configuring R8. For more information, see Limit the optimization scope.
In general, be careful with wildcards— make sure that you are keeping only
the code that you need to.
If you're unable to follow these rules, you might be using a lot of open-ended
reflection, and should either avoid the reflection or avoid the library using
reflection (see the Gson case study).
Content and code samples on this page are subject to the licenses described in the Content License. Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
Last updated 2025-08-21 UTC.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-08-21 UTC."],[],[],null,["# Follow the best practices\n\nWhile working with keep rules, it's important to reach the right amount of\nspecificity to make sure you see benefits while maintaining your app's\nbehaviour. See the following sections to learn about good patterns as well as\nthings to avoid in keep rules.\n\nGood patterns in keep rules\n---------------------------\n\nWell-defined keep rules are as specific as possible:\n\n- For the class specification, always specify a specific class, base class, or\n annotated class if possible, as shown in the following examples:\n\n -keepclassmembers class com.example.MyClass {\n void someSpecificMethod();\n }\n\n -keepclassmembers ** extends com.example.MyBaseClass {\n void someSpecificMethod();\n }\n\n -keepclassmembers @com.example.MyAnnotation class ** {\n void someSpecificMethod();\n }\n\n- Whenever possible, the member specification should be declared, and only\n reference the parts of the class that must be kept for the app to function.\n It's recommended to not apply a rule to an entire class by defining the\n optional member scope as `{ *; }` unless strictly needed.\n\n -keepclassmembers com.example.MyClass {\n void someSpecificMethod();\n void @com.example.MyAnnotation *;\n }\n\nIf you can't adhere to these guidelines, you can temporarily isolate the code\nthat needs to be kept in a dedicated package and apply your keep rule to the\npackage. However, this isn't a solution for the long term. To learn more, see\n[Adopt optimizations incrementally](/topic/performance/app-optimization/adopt-optimizations-incrementally#use-package-wide). To use a keep rule for a package define\na keep rule as shown in the following example: \n\n -keepclassmembers class com.example.pkg.** { *; }\n\nThings to avoid\n---------------\n\nThe keep rule syntax has many options, but for measurable sustainable\nperformance benefits we recommend not using the following:\n\n- Avoid using the inversion operator `!` in keep rules because you could unintentionally apply a rule to almost every class in your application.\n- Don't use package-wide keep rules such as `-keep class com.example.pkg.** {\n *; }` long-term. They can be used temporarily to work around issues when configuring R8. For more information, see [Limit the optimization scope](/topic/performance/app-optimization/adopt-optimizations-incrementally#limit-optimization). In general, be careful with wildcards--- make sure that you are keeping only the code that you need to.\n\nIf you're unable to follow these rules, you might be using a lot of open-ended\nreflection, and should either avoid the reflection or avoid the library using\nreflection (see the [Gson case study](/topic/performance/app-optimization/choose-libraries-wisely#gson-issues))."]]