Wrong View Cast in findViewById
ID |
java.android_wrong_view_cast |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
medium |
Resource |
Reliability |
Language |
Java |
Tags |
CWE:704, android, reliability |
Description
Reports mismatches between the cast target type of a (Type) findViewById(R.id.X) call in Java code and the XML tag declared for that id in a res/layout/*.xml file. At runtime, such a mismatch throws a ClassCastException when the view is inflated with a different widget type than the code expects.
Rationale
Android layout XML declares the concrete widget class for each view id. When Java code casts the result of findViewById() to a type that does not match the XML declaration, the cast fails at runtime:
// layout/activity_main.xml declares: <EditText android:id="@+id/userName" ... />
// Java code:
Button login = (Button) findViewById(R.id.userName); // ClassCastException!
The rule performs a strict simple-name match between the cast type and the XML tag. Casting (TextView) when the XML tag is <EditText> is flagged even though EditText extends TextView, because we do not load the Android widget type hierarchy. This may produce a small number of false positives for valid upcasts, which is an acceptable trade-off for catching real ClassCastException bugs.
If an id appears in multiple layout files with different XML tags, the rule skips that id to avoid false positives from layout variants (landscape, tablet, etc.).
Remediation
Ensure the cast type matches the XML tag, or use the generic View type and call type-safe accessor methods:
// Correct: cast matches the XML declaration
EditText userName = (EditText) findViewById(R.id.userName);
// Alternative: use View.findViewById with generics (API 26+)
EditText userName = findViewById(R.id.userName);