{"record":{"id":"1ddab640ab5b6a37","repo":"Blankj/AndroidUtilCode","slug":"u-can-t-instantiate-me-1ddab6","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/NumberUtils.java","lineNumber":30,"sourceCode":" *     time  : 2020/04/12\n *     desc  : utils about number\n * </pre>\n */\npublic final class NumberUtils {\n\n    private static final ThreadLocal<DecimalFormat> DF_THREAD_LOCAL = new ThreadLocal<DecimalFormat>() {\n        @Override\n        protected DecimalFormat initialValue() {\n            return (DecimalFormat) NumberFormat.getInstance();\n        }\n    };\n\n    public static DecimalFormat getSafeDecimalFormat() {\n        return DF_THREAD_LOCAL.get();\n    }\n\n    private NumberUtils() {\n        throw new UnsupportedOperationException(\"u can't instantiate me...\");\n    }\n\n    /**\n     * Format the value.\n     *\n     * @param value          The value.\n     * @param fractionDigits The number of digits allowed in the fraction portion of value.\n     * @return the format value\n     */\n    public static String format(float value, int fractionDigits) {\n        return format(value, false, 1, fractionDigits, true);\n    }\n\n    /**\n     * Format the value.\n     *\n     * @param value          The value.\n     * @param fractionDigits The number of digits allowed in the fraction portion of value.","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/Blankj/AndroidUtilCode/blob/7b4caf9e5440046b3fefb63b6b6e2ead7ebaf809/lib/utilcode/src/main/java/com/blankj/utilcode/util/NumberUtils.java#L12-L48","documentation":"NumberUtils is a utility class providing static methods for number formatting (format, int2Binary, binary2Int, etc.) with a ThreadLocal DecimalFormat for thread safety. Its private constructor throws UnsupportedOperationException to enforce static-only access.","triggerScenarios":"Direct or reflective instantiation by DI frameworks, mocking libraries, serialization frameworks, or manual reflection.","commonSituations":"Component scanning in DI traverses the utility package; a test framework instantiates all classes for coverage; a serialization library targets the class.","solutions":["Use static methods: NumberUtils.format(value, fractionDigits), NumberUtils.getSafeDecimalFormat(). Never call new NumberUtils().","Exclude utility classes from DI scanning and serialization configs.","Mock static methods with mockito-inline for testing."],"exampleFix":"// before\nNumberUtils nu = new NumberUtils();\nString formatted = nu.format(3.14159f, 2);\n\n// after\nString formatted = NumberUtils.format(3.14159f, 2);","handlingStrategy":"type-guard","validationCode":"// NumberUtils is static-only\nString formatted = NumberUtils.format(3.14159, 2);\nDecimalFormat df = NumberUtils.getSafeDecimalFormat();","typeGuard":"static boolean isStaticUtility(Class<?> c) {\n    return c.getSimpleName().endsWith(\"Utils\");\n}","tryCatchPattern":"try {\n    NumberUtils.class.getDeclaredConstructor().setAccessible(true);\n    NumberUtils.class.getDeclaredConstructor().newInstance();\n} catch (UnsupportedOperationException e) {\n    // Use static methods\n}","preventionTips":["Never instantiate classes ending in 'Utils'.","Exclude util packages from DI and serialization scanning.","Use NumberUtils.getSafeDecimalFormat() for thread-local DecimalFormat."],"tags":["java","android","utility-class","instantiation","number"],"backgroundTag":null,"analyzedSha":"7b4caf9e5440046b3fefb63b6b6e2ead7ebaf809","analyzedAt":"2026-08-14T02:26:54.956Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}