{"record":{"id":"f4596cd5aa62d193","repo":"Blankj/AndroidUtilCode","slug":"u-can-t-instantiate-me-f4596c","errorCode":null,"errorMessage":"u can't instantiate me...","messagePattern":"u can't instantiate me\\.\\.\\.","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"lib/utilcode/src/main/java/com/blankj/utilcode/util/ShellUtils.java","lineNumber":24,"sourceCode":"import java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.util.List;\n\n/**\n * <pre>\n *     author: Blankj\n *     blog  : http://blankj.com\n *     time  : 2016/08/07\n *     desc  : utils about shell\n * </pre>\n */\npublic final class ShellUtils {\n\n    private static final String LINE_SEP = System.getProperty(\"line.separator\");\n\n    private ShellUtils() {\n        throw new UnsupportedOperationException(\"u can't instantiate me...\");\n    }\n\n    /**\n     * Execute the command asynchronously.\n     *\n     * @param command  The command.\n     * @param isRooted True to use root, false otherwise.\n     * @param consumer The consumer.\n     * @return the task\n     */\n    public static Utils.Task<CommandResult> execCmdAsync(final String command,\n                                                         final boolean isRooted,\n                                                         final Utils.Consumer<CommandResult> consumer) {\n        return execCmdAsync(new String[]{command}, isRooted, true, consumer);\n    }\n\n    /**\n     * Execute the command asynchronously.","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/Blankj/AndroidUtilCode/blob/7b4caf9e5440046b3fefb63b6b6e2ead7ebaf809/lib/utilcode/src/main/java/com/blankj/utilcode/util/ShellUtils.java#L6-L42","documentation":"ShellUtils is a final static-only utility for executing shell commands (including optional root). Its private constructor throws UnsupportedOperationException to block instantiation. All public surface is static (execCmd, execCmdAsync), so construction is always a misuse.","triggerScenarios":"Reflective instantiation via ShellUtils.class.getDeclaredConstructor().setAccessible(true).newInstance(), or transitively via Gson/Jackson deserialization, Mockito/PowerMock mocking, Kotlin reflection, or a DI classpath scan.","commonSituations":"Tests mocking shell execution; JSON mapping a field to ShellUtils; coverage tooling probing classes; accidental instantiation after a fork weakened access modifiers.","solutions":["Use the static API: ShellUtils.execCmd(cmd, isRooted) instead of constructing the class.","Provide a Gson InstanceCreator or Jackson mixin that returns a sentinel/null so the constructor is never invoked.","For mocking, use Mockito.mockStatic on execCmd rather than constructing ShellUtils.","Keep the class final and constructor private to prevent accidental subclassing/instantiation."],"exampleFix":"// before\nShellUtils su = new ShellUtils(); // or via reflection\n\n// after\nShellUtils.CommandResult r = ShellUtils.execCmd(\"ls\", false);","handlingStrategy":"validation","validationCode":"if (Modifier.isFinal(ShellUtils.class.getModifiers())) {\n  throw new IllegalStateException(\"ShellUtils is static-only; call execCmd directly.\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Call ShellUtils.execCmd(...) statically; never construct.","Register Gson InstanceCreator/Jackson mixin for utility fields.","Mock static methods rather than instantiating.","Keep final + private constructor."],"tags":["android","utility-class","reflection","instantiation","shell"],"backgroundTag":null,"analyzedSha":"7b4caf9e5440046b3fefb63b6b6e2ead7ebaf809","analyzedAt":"2026-08-14T02:26:54.956Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}