{"record":{"id":"09d7a683d0c32d47","repo":"Blankj/AndroidUtilCode","slug":"u-can-t-instantiate-me-09d7a6","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/TouchUtils.java","lineNumber":35,"sourceCode":" *     time  : 2019/08/26\n *     desc  : utils about touch\n * </pre>\n */\npublic class TouchUtils {\n\n    public static final int UNKNOWN = 0;\n    public static final int LEFT    = 1;\n    public static final int UP      = 2;\n    public static final int RIGHT   = 4;\n    public static final int DOWN    = 8;\n\n    @IntDef({LEFT, UP, RIGHT, DOWN})\n    @Retention(RetentionPolicy.SOURCE)\n    public @interface Direction {\n    }\n\n    private TouchUtils() {\n        throw new UnsupportedOperationException(\"u can't instantiate me...\");\n    }\n\n    public static void setOnTouchListener(final View v, final OnTouchUtilsListener listener) {\n        if (v == null || listener == null) {\n            return;\n        }\n        v.setOnTouchListener(listener);\n    }\n\n    public static abstract class OnTouchUtilsListener implements View.OnTouchListener {\n\n        private static final int STATE_DOWN = 0;\n        private static final int STATE_MOVE = 1;\n        private static final int STATE_STOP = 2;\n\n        private static final int MIN_TAP_TIME = 1000;\n\n        private int touchSlop;","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/Blankj/AndroidUtilCode/blob/7b4caf9e5440046b3fefb63b6b6e2ead7ebaf809/lib/utilcode/src/main/java/com/blankj/utilcode/util/TouchUtils.java#L17-L53","documentation":"TouchUtils is a final static-only utility for attaching touch-direction listeners to Views. Its private constructor throws UnsupportedOperationException to block instantiation. All public methods (setOnTouchListener, etc.) are static and direction constants are class-level.","triggerScenarios":"Reflective instantiation via TouchUtils.class.getDeclaredConstructor().setAccessible(true).newInstance(), or transitively through Gson/Jackson deserialization, Mockito/PowerMock, Kotlin reflection, or a DI scan.","commonSituations":"Serialization frameworks binding a field to TouchUtils; mock frameworks in tests; coverage tooling; accidental `new TouchUtils()` after weakening modifiers.","solutions":["Call the static API: TouchUtils.setOnTouchListener(view, listener) instead of constructing.","Register a Gson InstanceCreator / Jackson mixin returning a sentinel so the constructor is not invoked.","Use Mockito.mockStatic for mocking rather than instantiation.","Keep the class final with a private constructor."],"exampleFix":"// before\nTouchUtils tu = new TouchUtils();\n\n// after\nTouchUtils.setOnTouchListener(view, listener);","handlingStrategy":"validation","validationCode":"if (Modifier.isFinal(TouchUtils.class.getModifiers())) {\n  throw new IllegalStateException(\"TouchUtils is static-only.\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Call TouchUtils.setOnTouchListener(...) statically.","Register InstanceCreator/mixin for JSON fields.","Use Mockito.mockStatic for mocking.","Keep final + private constructor."],"tags":["android","utility-class","reflection","instantiation","touch"],"backgroundTag":null,"analyzedSha":"7b4caf9e5440046b3fefb63b6b6e2ead7ebaf809","analyzedAt":"2026-08-14T02:26:54.956Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}