核心类方法补全: - Activity: +20方法 (requestWindowFeature, setTitle/getTitle, onKeyDown/onKeyUp, enterPictureInPictureMode, getReferrer, isTaskRoot, navigateUpTo等) - Fragment: +15方法 (getChildFragmentManager, getParentFragment, requireContext/requireActivity, setMenuVisibility等) - Intent: +20方法 (getParcelableExtra, setComponent/getComponent, getDataString, getScheme, putExtras等) - View: +20方法 (setLabelFor, setRotationX/Y, setForeground, setBackgroundTintList等) - KeyEvent: +7方法 (getCharacters, isSystem, isPrintingKey, isModifierKey, startTracking等) - Paint: +12方法 (setStrokeCap/Join, getTextBounds, setBlendMode, setLetterSpacing等) - Notification.Builder: +10方法 (setProgress, setShowWhen, setOnlyAlertOnce, setSound等) 存根转真实实现: - TrafficStats: 读取 /proc/net/dev 返回真实网络流量 - RecyclerView.Adapter: 观察者模式触发通知 - BaseAdapter: 观察者模式触发通知 - ExifInterface: 使用PIL实现图片翻转/旋转 - Process: 使用os.kill实现进程信号 - FileUtils: 真实文件I/O - SharedPreferences: 监听器模式 - TelephonyManager.listen: 维护监听器列表 - ScrollView.smoothScrollTo: 更新滚动位置 Exception体系扩展: - 新增15个Exception/Error类 (ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchElementException, AssertionError, OutOfMemoryError, StackOverflowError, NoClassDefFoundError, UnsatisfiedLinkError, LinkageError, VerifyError, AbstractMethodError, IncompatibleClassChangeError, ExceptionInInitializerError) Math/System/Thread/StringBuilder/Integer增强: - Math: +20方法 (subtractExact, multiplyExact, toIntExact, floorDiv/floorMod, fma等) - System: getProperties/setProperties/mapLibraryName/getLogger - Thread: +10方法 (getUncaughtExceptionHandler, getAllStackTraces, getStackTrace, holdLock等) - StringBuilder: +7方法 (ensureCapacity, trimToSize, setLength, subSequence等) - Integer: +8静态方法 (compare, compareUnsigned, divideUnsigned, sum, max, min等) 修复: - app_fragment.py: 使用java.lang.IllegalStateException替代本地定义 - content_intent.py: Intent.setData/getScheme正确从Uri提取scheme - view_ext.py: KeyEvent继承view.KeyEvent获取所有KEYCODE常量 - __init__.py: 补全Fragment/KeyEvent/MotionEvent/TrafficStats/RecyclerView等导出 统计: 221模块, 3660类, 30826方法, 180217行
2128 lines
56 KiB
Python
2128 lines
56 KiB
Python
"""
|
||
Java lang standard library APIs implemented in Python.
|
||
java.lang package - String, Integer, Math, Thread, System, Object, etc.
|
||
"""
|
||
|
||
from .._core import Stub, AndroidOnlyError
|
||
import re as _re
|
||
import math as _py_math
|
||
import sys as _sys
|
||
import os as _os
|
||
import platform
|
||
import time as _time
|
||
import threading as _threading
|
||
import inspect as _inspect
|
||
import math
|
||
import random
|
||
import time
|
||
from datetime import datetime as _datetime
|
||
|
||
__all__ = [
|
||
"Object", "Throwable", "Exception", "RuntimeException", "Error",
|
||
"NullPointerException", "IllegalArgumentException", "IllegalStateException",
|
||
"IndexOutOfBoundsException", "ArrayIndexOutOfBoundsException",
|
||
"StringIndexOutOfBoundsException", "ClassCastException",
|
||
"UnsupportedOperationException", "ArithmeticException",
|
||
"NumberFormatException", "SecurityException",
|
||
"ConcurrentModificationException", "NegativeArraySizeException",
|
||
"NoSuchFieldException", "NoSuchMethodException", "InterruptedException",
|
||
"CloneNotSupportedException", "IllegalMonitorStateException",
|
||
"IllegalThreadStateException", "EnumConstantNotPresentException",
|
||
"TypeNotPresentException",
|
||
"ClassNotFoundException", "IllegalAccessException", "InstantiationException",
|
||
"InvocationTargetException", "NoSuchElementException",
|
||
"AssertionError", "OutOfMemoryError", "StackOverflowError",
|
||
"NoClassDefFoundError", "UnsatisfiedLinkError", "LinkageError",
|
||
"VerifyError", "AbstractMethodError", "IncompatibleClassChangeError",
|
||
"ExceptionInInitializerError",
|
||
"String", "Integer", "Long", "Short", "Byte", "Float", "Double",
|
||
"Boolean", "Character", "Math", "StrictMath", "System",
|
||
"Thread", "ThreadLocal", "StringBuilder", "StringBuffer",
|
||
"Class", "Void", "VoidType",
|
||
"Stub", "Comparable", "CharSequence", "Iterable", "Appendable",
|
||
"Readable", "AutoCloseable", "Cloneable", "Runnable",
|
||
"StackTraceElement", "Number", "SuppressWarnings", "Deprecated",
|
||
"Override", "FunctionalInterface",
|
||
]
|
||
|
||
|
||
# ============================================================
|
||
# Interfaces
|
||
# ============================================================
|
||
|
||
class Comparable(Stub):
|
||
def compareTo(self, other):
|
||
raise NotImplementedError
|
||
|
||
class Iterable(Stub):
|
||
def iterator(self):
|
||
raise NotImplementedError
|
||
|
||
class AutoCloseable(Stub):
|
||
def close(self):
|
||
raise NotImplementedError
|
||
|
||
class Cloneable(Stub):
|
||
def clone(self):
|
||
return self.__class__()
|
||
|
||
class CharSequence(Stub):
|
||
def length(self):
|
||
raise NotImplementedError
|
||
def charAt(self, index):
|
||
raise NotImplementedError
|
||
def subSequence(self, start, end):
|
||
raise NotImplementedError
|
||
def toString(self):
|
||
raise NotImplementedError
|
||
|
||
class Appendable(Stub):
|
||
def append(self, c):
|
||
raise NotImplementedError
|
||
|
||
class Readable(Stub):
|
||
def read(self, cb):
|
||
raise NotImplementedError
|
||
|
||
class Runnable(Stub):
|
||
def run(self):
|
||
pass
|
||
|
||
|
||
# ============================================================
|
||
# Throwable hierarchy
|
||
# ============================================================
|
||
|
||
class Throwable(Exception, Stub):
|
||
def __init__(self, message=None, cause=None):
|
||
super().__init__(message or "")
|
||
self._detail_message = str(message) if message else None
|
||
self._cause = cause
|
||
self._stack_trace = []
|
||
self._suppressed = []
|
||
self._fill_in_stack()
|
||
|
||
def _fill_in_stack(self):
|
||
import traceback
|
||
stack = traceback.extract_stack()
|
||
self._stack_trace = [
|
||
StackTraceElement(
|
||
frame.filename, frame.name, frame.filename, frame.lineno, False
|
||
)
|
||
for frame in stack[:-1]
|
||
]
|
||
|
||
def getMessage(self):
|
||
return self._detail_message
|
||
|
||
def getLocalizedMessage(self):
|
||
return self._detail_message
|
||
|
||
def getCause(self):
|
||
return self._cause
|
||
|
||
def initCause(self, cause):
|
||
self._cause = cause
|
||
return self
|
||
|
||
def toString(self):
|
||
msg = self._detail_message or ""
|
||
return f"{self.__class__.__name__}: {msg}" if msg else self.__class__.__name__
|
||
|
||
def printStackTrace(self, file=None):
|
||
import traceback
|
||
if file is None:
|
||
file = _sys.stderr
|
||
traceback.print_exc(file=file)
|
||
|
||
def fillInStackTrace(self):
|
||
self._fill_in_stack()
|
||
return self
|
||
|
||
def getStackTrace(self):
|
||
return self._stack_trace
|
||
|
||
def setStackTrace(self, stack_trace):
|
||
self._stack_trace = stack_trace
|
||
|
||
def addSuppressed(self, exception):
|
||
self._suppressed.append(exception)
|
||
|
||
def getSuppressed(self):
|
||
return self._suppressed
|
||
|
||
def __str__(self):
|
||
return self.toString()
|
||
|
||
|
||
class Exception(Throwable):
|
||
pass
|
||
|
||
class RuntimeException(Exception):
|
||
pass
|
||
|
||
class Error(Throwable):
|
||
pass
|
||
|
||
|
||
class NullPointerException(RuntimeException):
|
||
pass
|
||
|
||
class IllegalArgumentException(RuntimeException):
|
||
pass
|
||
|
||
class IllegalStateException(RuntimeException):
|
||
pass
|
||
|
||
class IndexOutOfBoundsException(RuntimeException):
|
||
pass
|
||
|
||
class ArrayIndexOutOfBoundsException(IndexOutOfBoundsException):
|
||
pass
|
||
|
||
class StringIndexOutOfBoundsException(IndexOutOfBoundsException):
|
||
pass
|
||
|
||
class ClassCastException(RuntimeException):
|
||
pass
|
||
|
||
class UnsupportedOperationException(RuntimeException):
|
||
pass
|
||
|
||
class ArithmeticException(RuntimeException):
|
||
pass
|
||
|
||
class NumberFormatException(IllegalArgumentException):
|
||
pass
|
||
|
||
class SecurityException(RuntimeException):
|
||
pass
|
||
|
||
class ConcurrentModificationException(RuntimeException):
|
||
pass
|
||
|
||
class NegativeArraySizeException(RuntimeException):
|
||
pass
|
||
|
||
class NoSuchFieldException(Exception):
|
||
pass
|
||
|
||
class NoSuchMethodException(Exception):
|
||
pass
|
||
|
||
class InterruptedException(Exception):
|
||
pass
|
||
|
||
class CloneNotSupportedException(Exception):
|
||
pass
|
||
|
||
class IllegalMonitorStateException(RuntimeException):
|
||
pass
|
||
|
||
class IllegalThreadStateException(IllegalArgumentException):
|
||
pass
|
||
|
||
class EnumConstantNotPresentException(RuntimeException):
|
||
def __init__(self, e, constant):
|
||
super().__init__(f"{e}.{constant}")
|
||
self.enumType = e
|
||
self.constantName = constant
|
||
|
||
class TypeNotPresentException(RuntimeException):
|
||
def __init__(self, typeName, cause=None):
|
||
super().__init__(f"Type {typeName} not present", cause)
|
||
self.typeName = typeName
|
||
|
||
|
||
# ===== 缺失的 Exception 子类 =====
|
||
class ClassNotFoundException(Exception):
|
||
def __init__(self, message="", cause=None):
|
||
super().__init__(message, cause)
|
||
self.ex = message
|
||
|
||
class IllegalAccessException(Exception):
|
||
def __init__(self, message=""):
|
||
super().__init__(message)
|
||
|
||
class InstantiationException(Exception):
|
||
def __init__(self, message=""):
|
||
super().__init__(message)
|
||
|
||
class InvocationTargetException(Exception):
|
||
def __init__(self, target=None, cause=None):
|
||
if target is not None and cause is None:
|
||
super().__init__(str(target))
|
||
self.target = target
|
||
else:
|
||
super().__init__(str(target) if target else "", cause)
|
||
self.target = target
|
||
|
||
class NoSuchElementException(RuntimeException):
|
||
def __init__(self, message=""):
|
||
super().__init__(message)
|
||
|
||
# ===== 缺失的 Error 类 =====
|
||
class AssertionError(Error):
|
||
def __init__(self, message=None):
|
||
if message is None:
|
||
super().__init__("Assertion failed")
|
||
else:
|
||
super().__init__(str(message))
|
||
|
||
class OutOfMemoryError(Error):
|
||
def __init__(self, message=""):
|
||
super().__init__(message)
|
||
|
||
class StackOverflowError(Error):
|
||
def __init__(self, message=""):
|
||
super().__init__(message)
|
||
|
||
class NoClassDefFoundError(Error):
|
||
def __init__(self, message=""):
|
||
super().__init__(message)
|
||
|
||
class UnsatisfiedLinkError(Error):
|
||
def __init__(self, message=""):
|
||
super().__init__(message)
|
||
|
||
class LinkageError(Error):
|
||
def __init__(self, message=""):
|
||
super().__init__(message)
|
||
|
||
class VerifyError(LinkageError):
|
||
def __init__(self, message=""):
|
||
super().__init__(message)
|
||
|
||
class AbstractMethodError(LinkageError):
|
||
def __init__(self, message=""):
|
||
super().__init__(message)
|
||
|
||
class IncompatibleClassChangeError(LinkageError):
|
||
def __init__(self, message=""):
|
||
super().__init__(message)
|
||
|
||
class ExceptionInInitializerError(LinkageError):
|
||
def __init__(self, message="", cause=None):
|
||
super().__init__(message)
|
||
self._cause = cause
|
||
self.exception = cause
|
||
|
||
|
||
# ============================================================
|
||
# StackTraceElement
|
||
# ============================================================
|
||
|
||
class StackTraceElement(Stub):
|
||
def __init__(self, declaring_class, method_name, file_name, line_number, native_method):
|
||
super().__init__()
|
||
self._class = declaring_class
|
||
self._method = method_name
|
||
self._file = file_name
|
||
self._line = line_number
|
||
self._native = native_method
|
||
|
||
def getClassName(self):
|
||
return self._class
|
||
|
||
def getMethodName(self):
|
||
return self._method
|
||
|
||
def getFileName(self):
|
||
return self._file
|
||
|
||
def getLineNumber(self):
|
||
return self._line
|
||
|
||
def isNativeMethod(self):
|
||
return self._native
|
||
|
||
def toString(self):
|
||
return f"{self._class}.{self._method}({self._file}:{self._line})"
|
||
|
||
|
||
# ============================================================
|
||
# Object
|
||
# ============================================================
|
||
|
||
class Object(Stub):
|
||
def __init__(self):
|
||
super().__init__()
|
||
|
||
def getClass(self):
|
||
return self.__class__
|
||
|
||
def hashCode(self):
|
||
return hash(self) & 0x7FFFFFFF
|
||
|
||
def equals(self, other):
|
||
return self is other
|
||
|
||
def toString(self):
|
||
return f"{self.__class__.__name__}@{hex(id(self))}"
|
||
|
||
def notify(self):
|
||
pass
|
||
|
||
def notifyAll(self):
|
||
pass
|
||
|
||
def wait(self, timeout=None):
|
||
pass
|
||
|
||
def clone(self):
|
||
return self.__class__()
|
||
|
||
def finalize(self):
|
||
pass
|
||
|
||
|
||
# ============================================================
|
||
# String
|
||
# ============================================================
|
||
|
||
class String(CharSequence):
|
||
def __init__(self, value=None):
|
||
super().__init__()
|
||
if value is None:
|
||
self._str = ""
|
||
elif isinstance(value, bytes):
|
||
self._str = value.decode("utf-8", errors="replace")
|
||
else:
|
||
self._str = str(value)
|
||
|
||
def charAt(self, index):
|
||
return self._str[index]
|
||
|
||
def codePointAt(self, index):
|
||
return ord(self._str[index])
|
||
|
||
def codePointBefore(self, index):
|
||
return ord(self._str[index - 1]) if index > 0 else -1
|
||
|
||
def codePointCount(self, beginIndex, endIndex):
|
||
return endIndex - beginIndex
|
||
|
||
def compareTo(self, other):
|
||
if isinstance(other, String):
|
||
return (self._str > other._str) - (self._str < other._str)
|
||
return -1
|
||
|
||
def compareToIgnoreCase(self, other):
|
||
if isinstance(other, String):
|
||
return (self._str.lower() > other._str.lower()) - (self._str.lower() < other._str.lower())
|
||
return -1
|
||
|
||
def concat(self, s):
|
||
return String(self._str + str(s))
|
||
|
||
def contains(self, s):
|
||
return str(s) in self._str
|
||
|
||
def contentEquals(self, cs):
|
||
return self._str == str(cs)
|
||
|
||
def endsWith(self, suffix):
|
||
return self._str.endswith(suffix)
|
||
|
||
def equals(self, other):
|
||
if isinstance(other, String):
|
||
return self._str == other._str
|
||
return False
|
||
|
||
def equalsIgnoreCase(self, other):
|
||
if isinstance(other, String):
|
||
return self._str.lower() == other._str.lower()
|
||
return False
|
||
|
||
def getBytes(self, charset="UTF-8"):
|
||
return self._str.encode(charset, errors="replace")
|
||
|
||
def hashCode(self) -> int:
|
||
h = 0
|
||
for i in range(len(self._str)):
|
||
h = 31 * h + ord(self._str[i])
|
||
return h & 0x7FFFFFFF
|
||
|
||
def indexOf(self, ch, fromIndex=0):
|
||
if isinstance(ch, int):
|
||
ch = chr(ch)
|
||
return self._str.index(str(ch), fromIndex) if str(ch) in self._str[fromIndex:] else -1
|
||
|
||
def intern(self):
|
||
return self
|
||
|
||
def isEmpty(self):
|
||
return len(self._str) == 0
|
||
|
||
def lastIndexOf(self, ch, fromIndex=None):
|
||
if isinstance(ch, int):
|
||
ch = chr(ch)
|
||
if fromIndex is None:
|
||
fromIndex = len(self._str) - 1
|
||
search_in = self._str[:fromIndex + 1]
|
||
return search_in.rfind(str(ch)) if str(ch) in search_in else -1
|
||
|
||
def length(self):
|
||
return len(self._str)
|
||
|
||
def matches(self, regex):
|
||
return bool(_re.fullmatch(regex, self._str))
|
||
|
||
def offsetByCodePoints(self, index, codePointOffset):
|
||
return index + codePointOffset
|
||
|
||
def regionMatches(self, ignoreCase, toffset, other, ooffset, length):
|
||
if ignoreCase:
|
||
return self._str[toffset:toffset+length].lower() == other._str[ooffset:ooffset+length].lower()
|
||
return self._str[toffset:toffset+length] == other._str[ooffset:ooffset+length]
|
||
|
||
def replace(self, oldChar, newChar):
|
||
if isinstance(oldChar, int):
|
||
oldChar = chr(oldChar)
|
||
if isinstance(newChar, int):
|
||
newChar = chr(newChar)
|
||
return String(self._str.replace(oldChar, newChar))
|
||
|
||
def replaceAll(self, regex, replacement):
|
||
return String(_re.sub(regex, replacement, self._str))
|
||
|
||
def replaceFirst(self, regex, replacement):
|
||
return String(_re.sub(regex, replacement, self._str, count=1))
|
||
|
||
def split(self, regex, limit=0):
|
||
if limit <= 0:
|
||
parts = _re.split(regex, self._str)
|
||
if limit == 0:
|
||
while parts and parts[-1] == "":
|
||
parts.pop()
|
||
else:
|
||
parts = _re.split(regex, self._str, maxsplit=limit - 1)
|
||
while len(parts) < limit:
|
||
parts.append("")
|
||
return [String(p) for p in parts]
|
||
|
||
def startsWith(self, prefix):
|
||
return self._str.startswith(prefix)
|
||
|
||
def substring(self, beginIndex, endIndex=None):
|
||
if endIndex is None:
|
||
return String(self._str[beginIndex:])
|
||
return String(self._str[beginIndex:endIndex])
|
||
|
||
def toCharArray(self):
|
||
return list(self._str)
|
||
|
||
def toLowerCase(self):
|
||
return String(self._str.lower())
|
||
|
||
def toUpperCase(self):
|
||
return String(self._str.upper())
|
||
|
||
def trim(self):
|
||
return String(self._str.strip())
|
||
|
||
def strip(self):
|
||
return String(self._str.strip())
|
||
|
||
def stripLeading(self):
|
||
return String(self._str.lstrip())
|
||
|
||
def stripTrailing(self):
|
||
return String(self._str.rstrip())
|
||
|
||
def isBlank(self):
|
||
return self._str.strip() == ""
|
||
|
||
def repeat(self, count):
|
||
return String(self._str * count)
|
||
|
||
def lines(self):
|
||
from .util import ArrayList
|
||
result = ArrayList()
|
||
for line in self._str.splitlines():
|
||
result.add(String(line))
|
||
return result
|
||
|
||
def subSequence(self, start, end):
|
||
return self.substring(start, end)
|
||
|
||
def getChars(self, srcBegin, srcEnd, dst, dstBegin):
|
||
chars = self._str[srcBegin:srcEnd]
|
||
for i, c in enumerate(chars):
|
||
dst[dstBegin + i] = c
|
||
|
||
def chars(self):
|
||
return [ord(c) for c in self._str]
|
||
|
||
def formatted(self, *args):
|
||
return String(self._str.format(*args))
|
||
|
||
def translateEscapes(self):
|
||
result = []
|
||
s = self._str
|
||
i = 0
|
||
n = len(s)
|
||
while i < n:
|
||
c = s[i]
|
||
if c == '\\' and i + 1 < n:
|
||
nxt = s[i + 1]
|
||
if nxt == 'b':
|
||
result.append('\b'); i += 2
|
||
elif nxt == 't':
|
||
result.append('\t'); i += 2
|
||
elif nxt == 'n':
|
||
result.append('\n'); i += 2
|
||
elif nxt == 'f':
|
||
result.append('\f'); i += 2
|
||
elif nxt == 'r':
|
||
result.append('\r'); i += 2
|
||
elif nxt == 's':
|
||
result.append(' '); i += 2
|
||
elif nxt == '"':
|
||
result.append('"'); i += 2
|
||
elif nxt == "'":
|
||
result.append("'"); i += 2
|
||
elif nxt == '\\':
|
||
result.append('\\'); i += 2
|
||
elif nxt in '01234567':
|
||
octal = nxt
|
||
i += 2
|
||
max_digits = 2 if nxt in '0123' else 1
|
||
while len(octal) < max_digits + 1 and i < n and s[i] in '01234567':
|
||
octal += s[i]
|
||
i += 1
|
||
result.append(chr(int(octal, 8)))
|
||
elif nxt == '\n':
|
||
i += 2
|
||
elif nxt == '\r':
|
||
i += 2
|
||
if i < n and s[i] == '\n':
|
||
i += 1
|
||
else:
|
||
result.append(nxt); i += 2
|
||
else:
|
||
result.append(c); i += 1
|
||
return String(''.join(result))
|
||
|
||
@staticmethod
|
||
def valueOf(obj):
|
||
return String(str(obj))
|
||
|
||
@staticmethod
|
||
def copyValueOf(data, offset=0, count=None):
|
||
if count is None:
|
||
return String("".join(data))
|
||
return String("".join(data[offset:offset+count]))
|
||
|
||
@staticmethod
|
||
def format(fmt, *args):
|
||
return String(str(fmt) % args if args else str(fmt))
|
||
|
||
@staticmethod
|
||
def join(delimiter, *elements):
|
||
if hasattr(elements[0], '__iter__') and not isinstance(elements[0], (str, bytes)):
|
||
elements = elements[0]
|
||
return String(str(delimiter).join(str(s) for s in elements))
|
||
|
||
def toString(self):
|
||
return self._str
|
||
|
||
def __str__(self):
|
||
return self._str
|
||
|
||
def __repr__(self):
|
||
return f"String({self._str!r})"
|
||
|
||
def __len__(self):
|
||
return len(self._str)
|
||
|
||
def __getitem__(self, idx):
|
||
return self._str[idx]
|
||
|
||
def __add__(self, other):
|
||
return String(self._str + str(other))
|
||
|
||
def __eq__(self, other):
|
||
if isinstance(other, String):
|
||
return self._str == other._str
|
||
return NotImplemented
|
||
|
||
|
||
# ============================================================
|
||
# Number
|
||
# ============================================================
|
||
|
||
class Number(Stub):
|
||
def intValue(self):
|
||
raise NotImplementedError
|
||
def longValue(self):
|
||
raise NotImplementedError
|
||
def floatValue(self):
|
||
raise NotImplementedError
|
||
def doubleValue(self):
|
||
raise NotImplementedError
|
||
def byteValue(self):
|
||
return self.intValue() & 0xFF
|
||
def shortValue(self):
|
||
return self.intValue() & 0xFFFF
|
||
|
||
|
||
# ============================================================
|
||
# Integer
|
||
# ============================================================
|
||
|
||
class Integer(Number, Comparable):
|
||
MAX_VALUE = 2147483647
|
||
MIN_VALUE = -2147483648
|
||
SIZE = 32
|
||
BYTES = 4
|
||
TYPE = int
|
||
|
||
def __init__(self, value=0):
|
||
super().__init__()
|
||
if isinstance(value, str):
|
||
self._value = Integer.parseInt(value)
|
||
else:
|
||
self._value = int(value)
|
||
|
||
@staticmethod
|
||
def parseInt(s, radix=10):
|
||
if isinstance(s, String):
|
||
s = str(s)
|
||
if radix == 10:
|
||
return int(str(s))
|
||
return int(str(s), radix)
|
||
|
||
@staticmethod
|
||
def toString(i, radix=10):
|
||
if radix == 10:
|
||
return String(str(i))
|
||
if radix == 2:
|
||
return String(bin(i)[2:])
|
||
if radix == 8:
|
||
return String(oct(i)[2:])
|
||
if radix == 16:
|
||
return String(hex(i)[2:])
|
||
return String(str(i))
|
||
|
||
@staticmethod
|
||
def toBinaryString(i):
|
||
if i >= 0:
|
||
return String(bin(i)[2:])
|
||
return String(bin(i & 0xFFFFFFFF)[2:])
|
||
|
||
@staticmethod
|
||
def toHexString(i):
|
||
if i >= 0:
|
||
return String(hex(i)[2:])
|
||
return String(hex(i & 0xFFFFFFFF)[2:])
|
||
|
||
@staticmethod
|
||
def toOctalString(i):
|
||
if i >= 0:
|
||
return String(oct(i)[2:])
|
||
return String(oct(i & 0xFFFFFFFF)[2:])
|
||
|
||
@staticmethod
|
||
def valueOf(i, radix=10):
|
||
if isinstance(i, str):
|
||
return Integer(Integer.parseInt(i, radix))
|
||
return Integer(i)
|
||
|
||
def intValue(self):
|
||
return self._value
|
||
|
||
def compareTo(self, other):
|
||
if isinstance(other, Integer):
|
||
return (self._value > other._value) - (self._value < other._value)
|
||
return -1
|
||
|
||
def equals(self, other):
|
||
if isinstance(other, Integer):
|
||
return self._value == other._value
|
||
return False
|
||
|
||
def byteValue(self):
|
||
return self._value & 0xFF
|
||
|
||
def shortValue(self):
|
||
return self._value & 0xFFFF
|
||
|
||
def longValue(self):
|
||
return self._value
|
||
|
||
def floatValue(self):
|
||
return float(self._value)
|
||
|
||
def doubleValue(self):
|
||
return float(self._value)
|
||
|
||
@staticmethod
|
||
def bitCount(i):
|
||
return bin(i & 0xFFFFFFFF).count("1")
|
||
|
||
@staticmethod
|
||
def highestOneBit(i):
|
||
if i == 0:
|
||
return 0
|
||
return 1 << (i.bit_length() - 1)
|
||
|
||
@staticmethod
|
||
def lowestOneBit(i):
|
||
return i & -i
|
||
|
||
@staticmethod
|
||
def numberOfLeadingZeros(i):
|
||
if i == 0:
|
||
return 32
|
||
return 32 - i.bit_length()
|
||
|
||
@staticmethod
|
||
def numberOfTrailingZeros(i):
|
||
if i == 0:
|
||
return 32
|
||
return (i & -i).bit_length() - 1
|
||
|
||
@staticmethod
|
||
def reverse(i):
|
||
v = i & 0xFFFFFFFF
|
||
result = 0
|
||
for _ in range(32):
|
||
result = (result << 1) | (v & 1)
|
||
v >>= 1
|
||
return result
|
||
|
||
@staticmethod
|
||
def reverseBytes(i):
|
||
v = i & 0xFFFFFFFF
|
||
return ((v >> 24) & 0xFF) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000)
|
||
|
||
@staticmethod
|
||
def rotateLeft(i, distance):
|
||
v = i & 0xFFFFFFFF
|
||
d = distance & 31
|
||
return ((v << d) | (v >> (32 - d))) & 0xFFFFFFFF
|
||
|
||
@staticmethod
|
||
def rotateRight(i, distance):
|
||
v = i & 0xFFFFFFFF
|
||
d = distance & 31
|
||
return ((v >> d) | (v << (32 - d))) & 0xFFFFFFFF
|
||
|
||
@staticmethod
|
||
def signum(i):
|
||
if i > 0:
|
||
return 1
|
||
if i < 0:
|
||
return -1
|
||
return 0
|
||
|
||
@staticmethod
|
||
def decode(nm):
|
||
if nm.startswith("0x") or nm.startswith("0X"):
|
||
return Integer(int(nm, 16))
|
||
if nm.startswith("0") and len(nm) > 1:
|
||
return Integer(int(nm, 8))
|
||
if nm.startswith("#"):
|
||
return Integer(int(nm[1:], 16))
|
||
return Integer(int(nm))
|
||
|
||
@staticmethod
|
||
def getInteger(nm, val=None):
|
||
env_val = _os.environ.get(nm)
|
||
if env_val is not None:
|
||
return Integer(int(env_val))
|
||
return Integer(val) if val is not None else None
|
||
|
||
@staticmethod
|
||
def compare(x, y):
|
||
return -1 if x < y else (1 if x > y else 0)
|
||
|
||
@staticmethod
|
||
def compareUnsigned(x, y):
|
||
ux = x & 0xFFFFFFFF if x < 0 else x
|
||
uy = y & 0xFFFFFFFF if y < 0 else y
|
||
return -1 if ux < uy else (1 if ux > uy else 0)
|
||
|
||
@staticmethod
|
||
def divideUnsigned(dividend, divisor):
|
||
ux = dividend & 0xFFFFFFFF if dividend < 0 else dividend
|
||
uy = divisor & 0xFFFFFFFF if divisor < 0 else divisor
|
||
return ux // uy
|
||
|
||
@staticmethod
|
||
def remainderUnsigned(dividend, divisor):
|
||
ux = dividend & 0xFFFFFFFF if dividend < 0 else dividend
|
||
uy = divisor & 0xFFFFFFFF if divisor < 0 else divisor
|
||
return ux % uy
|
||
|
||
@staticmethod
|
||
def parseUnsignedInt(s, radix=10):
|
||
return int(s, radix)
|
||
|
||
@staticmethod
|
||
def toUnsignedString(i, radix=10):
|
||
if i < 0:
|
||
i = i & 0xFFFFFFFF
|
||
if radix == 10:
|
||
return str(i)
|
||
elif radix == 16:
|
||
return format(i, 'x')
|
||
elif radix == 2:
|
||
return format(i, 'b')
|
||
elif radix == 8:
|
||
return format(i, 'o')
|
||
return str(i)
|
||
|
||
@staticmethod
|
||
def toUnsignedLong(i):
|
||
return i & 0xFFFFFFFF
|
||
|
||
@staticmethod
|
||
def sum(a, b):
|
||
return a + b
|
||
|
||
@staticmethod
|
||
def max(a, b):
|
||
return a if a > b else b
|
||
|
||
@staticmethod
|
||
def min(a, b):
|
||
return a if a < b else b
|
||
|
||
def toString(self):
|
||
return String(str(self._value))
|
||
|
||
def __str__(self):
|
||
return str(self._value)
|
||
|
||
def __int__(self):
|
||
return self._value
|
||
|
||
|
||
# ============================================================
|
||
# Long
|
||
# ============================================================
|
||
|
||
class Long(Number, Comparable):
|
||
MAX_VALUE = 9223372036854775807
|
||
MIN_VALUE = -9223372036854775808
|
||
SIZE = 64
|
||
BYTES = 8
|
||
TYPE = int
|
||
|
||
def __init__(self, value=0):
|
||
super().__init__()
|
||
if isinstance(value, str):
|
||
self._value = Long.parseLong(value)
|
||
else:
|
||
self._value = int(value)
|
||
|
||
@staticmethod
|
||
def parseLong(s, radix=10):
|
||
if isinstance(s, String):
|
||
s = str(s)
|
||
if radix == 10:
|
||
return int(str(s))
|
||
return int(str(s), radix)
|
||
|
||
@staticmethod
|
||
def toString(i, radix=10):
|
||
if radix == 10:
|
||
return String(str(i))
|
||
return String(str(i))
|
||
|
||
@staticmethod
|
||
def toBinaryString(i):
|
||
if i >= 0:
|
||
return String(bin(i)[2:])
|
||
return String(bin(i & 0xFFFFFFFFFFFFFFFF)[2:])
|
||
|
||
@staticmethod
|
||
def toHexString(i):
|
||
if i >= 0:
|
||
return String(hex(i)[2:])
|
||
return String(hex(i & 0xFFFFFFFFFFFFFFFF)[2:])
|
||
|
||
@staticmethod
|
||
def toOctalString(i):
|
||
if i >= 0:
|
||
return String(oct(i)[2:])
|
||
return String(oct(i & 0xFFFFFFFFFFFFFFFF)[2:])
|
||
|
||
@staticmethod
|
||
def valueOf(i, radix=10):
|
||
if isinstance(i, str):
|
||
return Long(Long.parseLong(i, radix))
|
||
return Long(i)
|
||
|
||
def longValue(self):
|
||
return self._value
|
||
|
||
def intValue(self):
|
||
return int(self._value)
|
||
|
||
def floatValue(self):
|
||
return float(self._value)
|
||
|
||
def doubleValue(self):
|
||
return float(self._value)
|
||
|
||
def compareTo(self, other):
|
||
if isinstance(other, Long):
|
||
return (self._value > other._value) - (self._value < other._value)
|
||
return -1
|
||
|
||
def equals(self, other):
|
||
if isinstance(other, Long):
|
||
return self._value == other._value
|
||
return False
|
||
|
||
def toString(self):
|
||
return String(str(self._value))
|
||
|
||
def __str__(self):
|
||
return str(self._value)
|
||
|
||
|
||
# ============================================================
|
||
# Short, Byte
|
||
# ============================================================
|
||
|
||
class Short(Number, Comparable):
|
||
MAX_VALUE = 32767
|
||
MIN_VALUE = -32768
|
||
SIZE = 16
|
||
BYTES = 2
|
||
TYPE = int
|
||
|
||
def __init__(self, value=0):
|
||
super().__init__()
|
||
if isinstance(value, str):
|
||
self._value = Short.parseShort(value)
|
||
else:
|
||
self._value = int(value) & 0xFFFF
|
||
|
||
@staticmethod
|
||
def parseShort(s, radix=10):
|
||
return int(str(s), radix)
|
||
|
||
@staticmethod
|
||
def valueOf(i, radix=10):
|
||
if isinstance(i, str):
|
||
return Short(Short.parseShort(i, radix))
|
||
return Short(i)
|
||
|
||
def shortValue(self):
|
||
return self._value
|
||
|
||
def intValue(self):
|
||
return self._value
|
||
|
||
def longValue(self):
|
||
return self._value
|
||
|
||
def floatValue(self):
|
||
return float(self._value)
|
||
|
||
def doubleValue(self):
|
||
return float(self._value)
|
||
|
||
def compareTo(self, other):
|
||
if isinstance(other, Short):
|
||
return (self._value > other._value) - (self._value < other._value)
|
||
return -1
|
||
|
||
def equals(self, other):
|
||
if isinstance(other, Short):
|
||
return self._value == other._value
|
||
return False
|
||
|
||
def toString(self):
|
||
return String(str(self._value))
|
||
|
||
|
||
class Byte(Number, Comparable):
|
||
MAX_VALUE = 127
|
||
MIN_VALUE = -128
|
||
SIZE = 8
|
||
BYTES = 1
|
||
TYPE = int
|
||
|
||
def __init__(self, value=0):
|
||
super().__init__()
|
||
if isinstance(value, str):
|
||
self._value = Byte.parseByte(value)
|
||
else:
|
||
self._value = int(value) & 0xFF
|
||
if self._value > 127:
|
||
self._value -= 256
|
||
|
||
@staticmethod
|
||
def parseByte(s, radix=10):
|
||
return int(str(s), radix)
|
||
|
||
@staticmethod
|
||
def valueOf(i, radix=10):
|
||
if isinstance(i, str):
|
||
return Byte(Byte.parseByte(i, radix))
|
||
return Byte(i)
|
||
|
||
def byteValue(self):
|
||
return self._value
|
||
|
||
def intValue(self):
|
||
return self._value
|
||
|
||
def longValue(self):
|
||
return self._value
|
||
|
||
def compareTo(self, other):
|
||
if isinstance(other, Byte):
|
||
return (self._value > other._value) - (self._value < other._value)
|
||
return -1
|
||
|
||
def equals(self, other):
|
||
if isinstance(other, Byte):
|
||
return self._value == other._value
|
||
return False
|
||
|
||
def toString(self):
|
||
return String(str(self._value))
|
||
|
||
|
||
# ============================================================
|
||
# Float
|
||
# ============================================================
|
||
|
||
class Float(Number, Comparable):
|
||
MAX_VALUE = 3.4028235e38
|
||
MIN_VALUE = 1.4e-45
|
||
MIN_NORMAL = 1.17549435e-38
|
||
MAX_EXPONENT = 127
|
||
MIN_EXPONENT = -126
|
||
SIZE = 32
|
||
BYTES = 4
|
||
TYPE = float
|
||
NaN = float("nan")
|
||
POSITIVE_INFINITY = float("inf")
|
||
NEGATIVE_INFINITY = float("-inf")
|
||
|
||
def __init__(self, value=0.0):
|
||
super().__init__()
|
||
if isinstance(value, str):
|
||
self._value = Float.parseFloat(value)
|
||
else:
|
||
self._value = float(value)
|
||
|
||
@staticmethod
|
||
def parseFloat(s):
|
||
if isinstance(s, String):
|
||
s = str(s)
|
||
s = str(s).strip()
|
||
if s == "NaN":
|
||
return float("nan")
|
||
if s == "Infinity" or s == "Inf":
|
||
return float("inf")
|
||
if s == "-Infinity" or s == "-Inf":
|
||
return float("-inf")
|
||
return float(s)
|
||
|
||
@staticmethod
|
||
def toString(f):
|
||
return String(str(f))
|
||
|
||
@staticmethod
|
||
def valueOf(f):
|
||
if isinstance(f, str):
|
||
return Float(Float.parseFloat(f))
|
||
return Float(f)
|
||
|
||
def floatValue(self):
|
||
return self._value
|
||
|
||
def intValue(self):
|
||
return int(self._value)
|
||
|
||
def longValue(self):
|
||
return int(self._value)
|
||
|
||
def doubleValue(self):
|
||
return float(self._value)
|
||
|
||
def compareTo(self, other):
|
||
if isinstance(other, Float):
|
||
a, b = self._value, other._value
|
||
if _py_math.isnan(a) and _py_math.isnan(b):
|
||
return 0
|
||
if _py_math.isnan(a):
|
||
return 1
|
||
if _py_math.isnan(b):
|
||
return -1
|
||
return (a > b) - (a < b)
|
||
return -1
|
||
|
||
def isNaN(self):
|
||
return _py_math.isnan(self._value)
|
||
|
||
def isInfinite(self):
|
||
return _py_math.isinf(self._value)
|
||
|
||
def equals(self, other):
|
||
if isinstance(other, Float):
|
||
if _py_math.isnan(self._value) and _py_math.isnan(other._value):
|
||
return True
|
||
return self._value == other._value
|
||
return False
|
||
|
||
def hashCode(self):
|
||
return _struct.pack(">f", self._value)
|
||
|
||
def toString(self):
|
||
return String(str(self._value))
|
||
|
||
def __str__(self):
|
||
return str(self._value)
|
||
|
||
import struct as _struct
|
||
|
||
|
||
# ============================================================
|
||
# Double
|
||
# ============================================================
|
||
|
||
class Double(Number, Comparable):
|
||
MAX_VALUE = 1.7976931348623157e308
|
||
MIN_VALUE = 4.9e-324
|
||
MIN_NORMAL = 2.2250738585072014e-308
|
||
MAX_EXPONENT = 1023
|
||
MIN_EXPONENT = -1022
|
||
SIZE = 64
|
||
BYTES = 8
|
||
TYPE = float
|
||
NaN = float("nan")
|
||
POSITIVE_INFINITY = float("inf")
|
||
NEGATIVE_INFINITY = float("-inf")
|
||
|
||
def __init__(self, value=0.0):
|
||
super().__init__()
|
||
if isinstance(value, str):
|
||
self._value = Double.parseDouble(value)
|
||
else:
|
||
self._value = float(value)
|
||
|
||
@staticmethod
|
||
def parseDouble(s):
|
||
if isinstance(s, String):
|
||
s = str(s)
|
||
s = str(s).strip()
|
||
if s == "NaN":
|
||
return float("nan")
|
||
if s == "Infinity" or s == "Inf":
|
||
return float("inf")
|
||
if s == "-Infinity" or s == "-Inf":
|
||
return float("-inf")
|
||
return float(s)
|
||
|
||
@staticmethod
|
||
def toString(d):
|
||
return String(str(d))
|
||
|
||
@staticmethod
|
||
def valueOf(d):
|
||
if isinstance(d, str):
|
||
return Double(Double.parseDouble(d))
|
||
return Double(d)
|
||
|
||
def doubleValue(self):
|
||
return self._value
|
||
|
||
def intValue(self):
|
||
return int(self._value)
|
||
|
||
def longValue(self):
|
||
return int(self._value)
|
||
|
||
def floatValue(self):
|
||
return float(self._value)
|
||
|
||
def compareTo(self, other):
|
||
if isinstance(other, Double):
|
||
a, b = self._value, other._value
|
||
if _py_math.isnan(a) and _py_math.isnan(b):
|
||
return 0
|
||
if _py_math.isnan(a):
|
||
return 1
|
||
if _py_math.isnan(b):
|
||
return -1
|
||
return (a > b) - (a < b)
|
||
return -1
|
||
|
||
def isNaN(self):
|
||
return _py_math.isnan(self._value)
|
||
|
||
def isInfinite(self):
|
||
return _py_math.isinf(self._value)
|
||
|
||
def equals(self, other):
|
||
if isinstance(other, Double):
|
||
if _py_math.isnan(self._value) and _py_math.isnan(other._value):
|
||
return True
|
||
return self._value == other._value
|
||
return False
|
||
|
||
def toString(self):
|
||
return String(str(self._value))
|
||
|
||
def __str__(self):
|
||
return str(self._value)
|
||
|
||
|
||
# ============================================================
|
||
# Boolean
|
||
# ============================================================
|
||
|
||
class Boolean(Stub):
|
||
TRUE = "true"
|
||
FALSE = "false"
|
||
TYPE = bool
|
||
|
||
def __init__(self, value=False):
|
||
super().__init__()
|
||
if isinstance(value, str):
|
||
self._value = Boolean.parseBoolean(value)
|
||
elif isinstance(value, bool):
|
||
self._value = value
|
||
else:
|
||
self._value = bool(value)
|
||
|
||
@staticmethod
|
||
def parseBoolean(s):
|
||
return str(s).lower() == "true"
|
||
|
||
@staticmethod
|
||
def toString(b):
|
||
return String(str(b).lower())
|
||
|
||
@staticmethod
|
||
def valueOf(b):
|
||
if isinstance(b, str):
|
||
return Boolean(Boolean.parseBoolean(b))
|
||
return Boolean(b)
|
||
|
||
def booleanValue(self):
|
||
return self._value
|
||
|
||
@staticmethod
|
||
def logicalAnd(a, b):
|
||
return a and b
|
||
|
||
@staticmethod
|
||
def logicalOr(a, b):
|
||
return a or b
|
||
|
||
@staticmethod
|
||
def logicalXor(a, b):
|
||
return a ^ b
|
||
|
||
def compareTo(self, other):
|
||
if isinstance(other, Boolean):
|
||
return (self._value > other._value) - (self._value < other._value)
|
||
return -1
|
||
|
||
def equals(self, other):
|
||
if isinstance(other, Boolean):
|
||
return self._value == other._value
|
||
return False
|
||
|
||
def toString(self):
|
||
return String("true" if self._value else "false")
|
||
|
||
def __str__(self):
|
||
return "true" if self._value else "false"
|
||
|
||
def __bool__(self):
|
||
return self._value
|
||
|
||
|
||
# ============================================================
|
||
# Character
|
||
# ============================================================
|
||
|
||
class Character(Stub):
|
||
MAX_VALUE = 65535
|
||
MIN_VALUE = 0
|
||
SIZE = 16
|
||
BYTES = 2
|
||
TYPE = str
|
||
|
||
def __init__(self, value=""):
|
||
super().__init__()
|
||
if isinstance(value, int):
|
||
self._value = chr(value)
|
||
else:
|
||
self._value = str(value)[0] if value else ""
|
||
|
||
def charValue(self):
|
||
return self._value
|
||
|
||
@staticmethod
|
||
def isDigit(ch):
|
||
return str(ch).isdigit()
|
||
|
||
@staticmethod
|
||
def isLetter(ch):
|
||
return str(ch).isalpha()
|
||
|
||
@staticmethod
|
||
def isLetterOrDigit(ch):
|
||
return str(ch).isalnum()
|
||
|
||
@staticmethod
|
||
def isLowerCase(ch):
|
||
return str(ch).islower()
|
||
|
||
@staticmethod
|
||
def isUpperCase(ch):
|
||
return str(ch).isupper()
|
||
|
||
@staticmethod
|
||
def isWhitespace(ch):
|
||
return str(ch).isspace()
|
||
|
||
@staticmethod
|
||
def isSpaceChar(ch):
|
||
return str(ch) in " \t\n\r\f\u000B"
|
||
|
||
@staticmethod
|
||
def isISOControl(ch):
|
||
c = ord(ch) if isinstance(ch, str) else ch
|
||
return c < 0x20 or c == 0x7F
|
||
|
||
@staticmethod
|
||
def isJavaIdentifierPart(ch):
|
||
c = str(ch)
|
||
return c.isalnum() or c == "_" or c == "$"
|
||
|
||
@staticmethod
|
||
def isJavaIdentifierStart(ch):
|
||
c = str(ch)
|
||
return c.isalpha() or c == "_" or c == "$"
|
||
|
||
@staticmethod
|
||
def isJavaLetter(ch):
|
||
return Character.isJavaIdentifierStart(ch)
|
||
|
||
@staticmethod
|
||
def isJavaLetterOrDigit(ch):
|
||
return Character.isJavaIdentifierPart(ch)
|
||
|
||
@staticmethod
|
||
def toLowerCase(ch):
|
||
return str(ch).lower()
|
||
|
||
@staticmethod
|
||
def toUpperCase(ch):
|
||
return str(ch).upper()
|
||
|
||
@staticmethod
|
||
def toTitleCase(ch):
|
||
return str(ch).upper()
|
||
|
||
@staticmethod
|
||
def getNumericValue(ch):
|
||
s = str(ch)
|
||
if s.isdigit():
|
||
return int(s)
|
||
if "a" <= s <= "z":
|
||
return ord(s) - ord("a") + 10
|
||
if "A" <= s <= "Z":
|
||
return ord(s) - ord("A") + 10
|
||
return -1
|
||
|
||
@staticmethod
|
||
def digit(ch, radix):
|
||
val = Character.getNumericValue(ch)
|
||
return val if val < radix else -1
|
||
|
||
@staticmethod
|
||
def forDigit(digit, radix):
|
||
if digit >= radix:
|
||
return "\0"
|
||
return str(digit) if digit < 10 else chr(ord("a") + digit - 10)
|
||
|
||
@staticmethod
|
||
def getType(ch):
|
||
return 0
|
||
|
||
@staticmethod
|
||
def getDirectionality(ch):
|
||
return 0
|
||
|
||
@staticmethod
|
||
def getName(ch):
|
||
return f"CHARACTER {ord(ch)}"
|
||
|
||
@staticmethod
|
||
def charCount(codePoint):
|
||
return 1 if codePoint < 0x10000 else 2
|
||
|
||
@staticmethod
|
||
def isBmpCodePoint(cp):
|
||
return cp <= 0xFFFF
|
||
|
||
@staticmethod
|
||
def isHighSurrogate(ch):
|
||
c = ord(ch) if isinstance(ch, str) else ch
|
||
return 0xD800 <= c <= 0xDBFF
|
||
|
||
@staticmethod
|
||
def isLowSurrogate(ch):
|
||
c = ord(ch) if isinstance(ch, str) else ch
|
||
return 0xDC00 <= c <= 0xDFFF
|
||
|
||
@staticmethod
|
||
def isSupplementaryCodePoint(cp):
|
||
return 0x10000
|
||
|
||
|
||
class Math:
|
||
"""java.lang.Math — 数学运算"""
|
||
E = 2.718281828459045
|
||
PI = 3.141592653589793
|
||
|
||
@staticmethod
|
||
def abs(a): return abs(a)
|
||
@staticmethod
|
||
def ceil(a): return int(math.ceil(a))
|
||
@staticmethod
|
||
def floor(a): return int(math.floor(a))
|
||
@staticmethod
|
||
def round(a: float) -> int:
|
||
return int(math.floor(a + 0.5))
|
||
@staticmethod
|
||
def min(a, b): return a if a < b else b
|
||
@staticmethod
|
||
def max(a, b): return a if a > b else b
|
||
@staticmethod
|
||
def sqrt(a): return math.sqrt(a)
|
||
@staticmethod
|
||
def cbrt(a): return math.cbrt(a)
|
||
@staticmethod
|
||
def pow(a, b): return math.pow(a, b)
|
||
@staticmethod
|
||
def exp(a): return math.exp(a)
|
||
@staticmethod
|
||
def log(a): return math.log(a)
|
||
@staticmethod
|
||
def log10(a): return math.log10(a)
|
||
@staticmethod
|
||
def sin(a): return math.sin(a)
|
||
@staticmethod
|
||
def cos(a): return math.cos(a)
|
||
@staticmethod
|
||
def tan(a): return math.tan(a)
|
||
@staticmethod
|
||
def asin(a): return math.asin(a)
|
||
@staticmethod
|
||
def acos(a): return math.acos(a)
|
||
@staticmethod
|
||
def atan(a): return math.atan(a)
|
||
@staticmethod
|
||
def atan2(y, x): return math.atan2(y, x)
|
||
@staticmethod
|
||
def toDegrees(r): return math.degrees(r)
|
||
@staticmethod
|
||
def toRadians(d): return math.radians(d)
|
||
@staticmethod
|
||
def hypot(x, y): return math.hypot(x, y)
|
||
@staticmethod
|
||
def sinh(x): return math.sinh(x)
|
||
@staticmethod
|
||
def cosh(x): return math.cosh(x)
|
||
@staticmethod
|
||
def tanh(x): return math.tanh(x)
|
||
@staticmethod
|
||
def signum(x): return 0.0 if x == 0 else (1.0 if x > 0 else -1.0)
|
||
@staticmethod
|
||
def random(): return random.random()
|
||
@staticmethod
|
||
def addExact(x, y):
|
||
result = x + y
|
||
if (x > 0 and y > 0 and result < 0) or (x < 0 and y < 0 and result > 0):
|
||
raise ArithmeticError("integer overflow")
|
||
return result
|
||
@staticmethod
|
||
def copySign(m, s): return abs(m) * (1 if s >= 0 else -1)
|
||
@staticmethod
|
||
def floorDiv(x, y):
|
||
return math.floor(x / y) if y != 0 else 0
|
||
@staticmethod
|
||
def floorMod(x, y):
|
||
return x - Math.floorDiv(x, y) * y
|
||
@staticmethod
|
||
def subtractExact(x, y):
|
||
result = x - y
|
||
if isinstance(x, int) and isinstance(y, int):
|
||
if result > 0 and x < 0 and y > 0:
|
||
raise ArithmeticException("integer overflow")
|
||
if result < 0 and x > 0 and y < 0:
|
||
raise ArithmeticException("integer overflow")
|
||
return result
|
||
@staticmethod
|
||
def multiplyExact(x, y):
|
||
result = x * y
|
||
if isinstance(x, int) and isinstance(y, int):
|
||
if result // y != x:
|
||
raise ArithmeticException("integer overflow")
|
||
return result
|
||
@staticmethod
|
||
def incrementExact(a):
|
||
if a == 2147483647:
|
||
raise ArithmeticException("integer overflow")
|
||
return a + 1
|
||
@staticmethod
|
||
def decrementExact(a):
|
||
if a == -2147483648:
|
||
raise ArithmeticException("integer overflow")
|
||
return a - 1
|
||
@staticmethod
|
||
def negateExact(a):
|
||
if a == -2147483648:
|
||
raise ArithmeticException("integer overflow")
|
||
return -a
|
||
@staticmethod
|
||
def toIntExact(value):
|
||
if value < -2147483648 or value > 2147483647:
|
||
raise ArithmeticException("integer overflow")
|
||
return int(value)
|
||
@staticmethod
|
||
def log1p(x):
|
||
return math.log1p(x)
|
||
@staticmethod
|
||
def expm1(x):
|
||
return math.expm1(x)
|
||
@staticmethod
|
||
def ulp(x):
|
||
return math.ulp(x) if hasattr(math, 'ulp') else abs(x) * 2.220446049250313e-16
|
||
@staticmethod
|
||
def getExponent(x):
|
||
return math.frexp(x)[1] - 1
|
||
@staticmethod
|
||
def nextAfter(start, direction):
|
||
return math.nextafter(start, direction)
|
||
@staticmethod
|
||
def nextUp(x):
|
||
return math.nextafter(x, math.inf)
|
||
@staticmethod
|
||
def nextDown(x):
|
||
return math.nextafter(x, -math.inf)
|
||
@staticmethod
|
||
def rint(x):
|
||
return math.rint(x) if hasattr(math, 'rint') else float(math.floor(x + 0.5))
|
||
@staticmethod
|
||
def IEEEremainder(x, y):
|
||
return math.remainder(x, y) if hasattr(math, 'remainder') else x - y * math.floor(x / y)
|
||
@staticmethod
|
||
def compareUnsigned(x, y):
|
||
ux = x & 0xFFFFFFFF if x < 0 else x
|
||
uy = y & 0xFFFFFFFF if y < 0 else y
|
||
return -1 if ux < uy else (1 if ux > uy else 0)
|
||
@staticmethod
|
||
def divideUnsigned(dividend, divisor):
|
||
ux = dividend & 0xFFFFFFFF if dividend < 0 else dividend
|
||
uy = divisor & 0xFFFFFFFF if divisor < 0 else divisor
|
||
return ux // uy
|
||
@staticmethod
|
||
def remainderUnsigned(dividend, divisor):
|
||
ux = dividend & 0xFFFFFFFF if dividend < 0 else dividend
|
||
uy = divisor & 0xFFFFFFFF if divisor < 0 else divisor
|
||
return ux % uy
|
||
@staticmethod
|
||
def fma(a, b, c):
|
||
return a * b + c
|
||
|
||
|
||
class StrictMath(Math):
|
||
"""java.lang.StrictMath"""
|
||
pass
|
||
|
||
|
||
class _Console:
|
||
"""java.io.Console 简化实现,供 System.console() 使用"""
|
||
def readLine(self, fmt=None, *args):
|
||
if fmt is not None:
|
||
try:
|
||
_sys.stdout.write(str(fmt) % args if args else str(fmt))
|
||
except Exception:
|
||
_sys.stdout.write(str(fmt))
|
||
_sys.stdout.flush()
|
||
line = _sys.stdin.readline()
|
||
if line == "":
|
||
return None
|
||
return line.rstrip("\r\n")
|
||
|
||
def readPassword(self, fmt=None, *args):
|
||
import getpass
|
||
if fmt is not None:
|
||
try:
|
||
_sys.stderr.write(str(fmt) % args if args else str(fmt))
|
||
except Exception:
|
||
_sys.stderr.write(str(fmt))
|
||
_sys.stderr.flush()
|
||
pwd = getpass.getpass("")
|
||
return list(pwd) if pwd is not None else None
|
||
|
||
def printf(self, fmt, *args):
|
||
try:
|
||
_sys.stdout.write(str(fmt) % args if args else str(fmt))
|
||
except Exception:
|
||
_sys.stdout.write(str(fmt))
|
||
return self
|
||
|
||
def format(self, fmt, *args):
|
||
try:
|
||
_sys.stdout.write(str(fmt) % args if args else str(fmt))
|
||
except Exception:
|
||
_sys.stdout.write(str(fmt))
|
||
return self
|
||
|
||
def flush(self):
|
||
_sys.stdout.flush()
|
||
|
||
def writer(self):
|
||
return _sys.stdout
|
||
|
||
def reader(self):
|
||
return _sys.stdin
|
||
|
||
|
||
class System:
|
||
"""java.lang.System"""
|
||
_console = None
|
||
@staticmethod
|
||
def currentTimeMillis(): return int(time.time() * 1000)
|
||
@staticmethod
|
||
def nanoTime(): return time.perf_counter_ns()
|
||
@staticmethod
|
||
def arraycopy(src, srcPos, dest, destPos, length):
|
||
if isinstance(src, (list, bytearray)):
|
||
dest[destPos:destPos+length] = src[srcPos:srcPos+length]
|
||
else:
|
||
raise TypeError("Unsupported type for arraycopy")
|
||
@staticmethod
|
||
def identityHashCode(obj): return id(obj) & 0x7FFFFFFF
|
||
@staticmethod
|
||
def gc(): pass
|
||
@staticmethod
|
||
def exit(status): raise SystemExit(status)
|
||
@staticmethod
|
||
def getProperty(key, default=None):
|
||
import os
|
||
return os.environ.get(key, default)
|
||
@staticmethod
|
||
def setProperty(key, value):
|
||
import os
|
||
os.environ[key] = value
|
||
return value
|
||
@staticmethod
|
||
def clearProperty(key):
|
||
return _os.environ.pop(key, None)
|
||
@staticmethod
|
||
def getenv(name=None):
|
||
if name is None:
|
||
return dict(_os.environ)
|
||
return _os.environ.get(name)
|
||
@staticmethod
|
||
def console():
|
||
if System._console is None:
|
||
System._console = _Console()
|
||
return System._console
|
||
@staticmethod
|
||
def setIn(in_stream):
|
||
System.in_ = in_stream
|
||
@staticmethod
|
||
def setOut(out_stream):
|
||
System.out = out_stream
|
||
@staticmethod
|
||
def setErr(err_stream):
|
||
System.err = err_stream
|
||
@staticmethod
|
||
def lineSeparator(): return _os.linesep
|
||
@staticmethod
|
||
def getProperties():
|
||
return {
|
||
"java.version": "1.8.0",
|
||
"java.vendor": "Android-pyApi",
|
||
"java.vendor.url": "https://gitee.com/shuiyu1123/Android-pyApi",
|
||
"java.home": _os.environ.get("JAVA_HOME", ""),
|
||
"java.class.version": "52.0",
|
||
"os.name": platform.system(),
|
||
"os.arch": platform.machine(),
|
||
"os.version": platform.release(),
|
||
"file.separator": _os.sep,
|
||
"path.separator": _os.pathsep,
|
||
"line.separator": _os.linesep,
|
||
"user.name": _os.environ.get("USER", _os.environ.get("USERNAME", "")),
|
||
"user.home": _os.path.expanduser("~"),
|
||
"user.dir": _os.getcwd(),
|
||
}
|
||
@staticmethod
|
||
def setProperties(props):
|
||
System._properties = props
|
||
@staticmethod
|
||
def mapLibraryName(libname):
|
||
if platform.system() == "Windows":
|
||
return libname + ".dll"
|
||
elif platform.system() == "Darwin":
|
||
return "lib" + libname + ".dylib"
|
||
else:
|
||
return "lib" + libname + ".so"
|
||
@staticmethod
|
||
def getLogger(name):
|
||
import logging
|
||
return logging.getLogger(name)
|
||
in_ = _sys.stdin
|
||
out = _sys.stdout
|
||
err = _sys.stderr
|
||
|
||
|
||
class Thread(Runnable):
|
||
"""java.lang.Thread"""
|
||
MIN_PRIORITY = 1
|
||
NORM_PRIORITY = 5
|
||
MAX_PRIORITY = 10
|
||
|
||
# Thread.State 常量(java.lang.Thread.State)
|
||
NEW = "NEW"
|
||
RUNNABLE = "RUNNABLE"
|
||
BLOCKED = "BLOCKED"
|
||
WAITING = "WAITING"
|
||
TIMED_WAITING = "TIMED_WAITING"
|
||
TERMINATED = "TERMINATED"
|
||
|
||
# 按 Python 线程 ident 缓存 Thread 对象,供 currentThread() 复用
|
||
_thread_cache = {}
|
||
_default_uncaught_exception_handler = None
|
||
|
||
def __init__(self, target=None, name=None):
|
||
super().__init__()
|
||
self._target = target
|
||
self._name = name or f"Thread-{id(self)}"
|
||
self._alive = False
|
||
self._daemon = False
|
||
self._interrupted = False
|
||
self._priority = Thread.NORM_PRIORITY
|
||
self._state = Thread.NEW
|
||
self._py_thread = None
|
||
self._id = _threading.get_ident()
|
||
|
||
def start(self):
|
||
self._alive = True
|
||
self._state = Thread.RUNNABLE
|
||
self._py_thread = _threading.Thread(
|
||
target=self._run_wrapper, daemon=self._daemon, name=self._name
|
||
)
|
||
self._py_thread.start()
|
||
self._id = self._py_thread.ident
|
||
|
||
def _run_wrapper(self):
|
||
tid = _threading.get_ident()
|
||
self._id = tid
|
||
Thread._thread_cache[tid] = self
|
||
try:
|
||
self.run()
|
||
except (SystemExit, KeyboardInterrupt):
|
||
raise
|
||
except BaseException as e:
|
||
# 注意:模块内 Exception 已被 java.lang.Exception 覆盖,
|
||
# 这里用 BaseException 捕获 Python 原生异常并转发给未捕获异常处理器
|
||
handler = Thread._default_uncaught_exception_handler
|
||
if handler is not None:
|
||
try:
|
||
handler.uncaughtException(self, e)
|
||
except BaseException:
|
||
pass
|
||
finally:
|
||
self._alive = False
|
||
self._state = Thread.TERMINATED
|
||
Thread._thread_cache.pop(tid, None)
|
||
|
||
def run(self):
|
||
if self._target:
|
||
self._target()
|
||
|
||
def join(self, millis=0):
|
||
if self._py_thread is not None:
|
||
if millis and millis > 0:
|
||
self._py_thread.join(millis / 1000.0)
|
||
else:
|
||
self._py_thread.join()
|
||
|
||
def interrupt(self):
|
||
self._interrupted = True
|
||
|
||
def isInterrupted(self):
|
||
return self._interrupted
|
||
|
||
@staticmethod
|
||
def interrupted():
|
||
tid = _threading.get_ident()
|
||
t = Thread._thread_cache.get(tid)
|
||
if t is not None:
|
||
status = t._interrupted
|
||
t._interrupted = False
|
||
return status
|
||
return False
|
||
|
||
def isAlive(self):
|
||
if self._py_thread is not None:
|
||
return self._py_thread.is_alive()
|
||
return self._alive
|
||
|
||
def getState(self):
|
||
if self._py_thread is not None:
|
||
if self._py_thread.is_alive():
|
||
return Thread.RUNNABLE
|
||
return Thread.TERMINATED
|
||
return self._state
|
||
|
||
def getPriority(self):
|
||
return self._priority
|
||
|
||
def setPriority(self, priority):
|
||
if Thread.MIN_PRIORITY <= priority <= Thread.MAX_PRIORITY:
|
||
self._priority = priority
|
||
|
||
def getId(self):
|
||
return self._id
|
||
|
||
def getName(self): return self._name
|
||
def setName(self, n): self._name = n
|
||
def setDaemon(self, d): self._daemon = d
|
||
def isDaemon(self): return self._daemon
|
||
|
||
@staticmethod
|
||
def currentThread():
|
||
tid = _threading.get_ident()
|
||
t = Thread._thread_cache.get(tid)
|
||
if t is not None:
|
||
return t
|
||
# 未缓存的线程(如主线程):创建并缓存一个代表对象
|
||
try:
|
||
is_main = (tid == _threading.main_thread().ident)
|
||
except Exception:
|
||
is_main = False
|
||
t = Thread(name="main" if is_main else f"Thread-{tid}")
|
||
t._state = Thread.RUNNABLE
|
||
t._alive = True
|
||
t._id = tid
|
||
Thread._thread_cache[tid] = t
|
||
return t
|
||
|
||
@staticmethod
|
||
def sleep(millis):
|
||
_time.sleep(millis / 1000.0)
|
||
|
||
@staticmethod
|
||
def yield_():
|
||
_time.sleep(0)
|
||
|
||
@staticmethod
|
||
def setDefaultUncaughtExceptionHandler(handler):
|
||
Thread._default_uncaught_exception_handler = handler
|
||
|
||
@staticmethod
|
||
def getDefaultUncaughtExceptionHandler():
|
||
return Thread._default_uncaught_exception_handler
|
||
|
||
def getUncaughtExceptionHandler(self):
|
||
return getattr(self, '_uncaught_handler', Thread._default_uncaught_exception_handler)
|
||
|
||
def setUncaughtExceptionHandler(self, handler):
|
||
self._uncaught_handler = handler
|
||
|
||
@staticmethod
|
||
def getAllStackTraces():
|
||
import traceback
|
||
result = {}
|
||
# 只返回当前线程
|
||
result[Thread.currentThread()] = traceback.extract_stack()
|
||
return result
|
||
|
||
def getStackTrace(self):
|
||
import traceback
|
||
return traceback.extract_stack()
|
||
|
||
@staticmethod
|
||
def enumerate(array):
|
||
# 返回活动线程数
|
||
return 0
|
||
|
||
@staticmethod
|
||
def activeCount():
|
||
import threading
|
||
return threading.active_count()
|
||
|
||
def getContextClassLoader(self):
|
||
return getattr(self, '_context_classloader', None)
|
||
|
||
def setContextClassLoader(self, cl):
|
||
self._context_classloader = cl
|
||
|
||
def getThreadGroup(self):
|
||
return getattr(self, '_thread_group', None)
|
||
|
||
@staticmethod
|
||
def holdLock(obj):
|
||
return False
|
||
|
||
@staticmethod
|
||
def dumpStack():
|
||
import traceback
|
||
traceback.print_stack()
|
||
|
||
@staticmethod
|
||
def onSpinWait():
|
||
pass
|
||
|
||
def isVirtual(self):
|
||
return False
|
||
|
||
@staticmethod
|
||
def ofVirtual():
|
||
"""创建虚拟线程 (Java 21+)"""
|
||
t = Thread(target=lambda: None)
|
||
t._virtual = True
|
||
return t
|
||
|
||
|
||
class ThreadLocal(Stub):
|
||
"""java.lang.ThreadLocal"""
|
||
def __init__(self):
|
||
super().__init__()
|
||
self._data = {}
|
||
|
||
def get(self):
|
||
tid = _threading.get_ident()
|
||
return self._data.get(tid, None)
|
||
def set(self, value):
|
||
self._data[_threading.get_ident()] = value
|
||
def remove(self):
|
||
self._data.pop(_threading.get_ident(), None)
|
||
|
||
|
||
class StringBuilder(Stub):
|
||
"""java.lang.StringBuilder — 可变字符序列"""
|
||
def __init__(self, s=""):
|
||
super().__init__()
|
||
self._buf = list(str(s))
|
||
|
||
def append(self, obj):
|
||
if isinstance(obj, bool):
|
||
self._buf.append("true" if obj else "false")
|
||
else:
|
||
self._buf.append(str(obj))
|
||
return self
|
||
|
||
def insert(self, offset, obj):
|
||
self._buf[offset:offset] = list(str(obj))
|
||
return self
|
||
|
||
def delete(self, start, end):
|
||
del self._buf[start:end]
|
||
return self
|
||
|
||
def deleteCharAt(self, index):
|
||
del self._buf[index]
|
||
return self
|
||
|
||
def replace(self, start, end, s):
|
||
self._buf[start:end] = list(s)
|
||
return self
|
||
|
||
def reverse(self):
|
||
self._buf.reverse()
|
||
return self
|
||
|
||
def toString(self): return "".join(self._buf)
|
||
def length(self): return len(self._buf)
|
||
def capacity(self): return len(self._buf) + 16
|
||
def charAt(self, i): return self._buf[i]
|
||
def setCharAt(self, i, c): self._buf[i] = c
|
||
def substring(self, s, e=None):
|
||
return "".join(self._buf[s:e])
|
||
def indexOf(self, s, f=0):
|
||
return self.toString().find(s, f)
|
||
def lastIndexOf(self, s, f=None):
|
||
return self.toString().rfind(s)
|
||
|
||
def ensureCapacity(self, minimumCapacity):
|
||
pass # Python list 自动扩容
|
||
|
||
def trimToSize(self):
|
||
pass
|
||
|
||
def setLength(self, newLength):
|
||
current = len(self._buf)
|
||
if newLength < current:
|
||
del self._buf[newLength:]
|
||
else:
|
||
self._buf.extend([" "] * (newLength - current))
|
||
|
||
def subSequence(self, start, end):
|
||
return "".join(self._buf[start:end])
|
||
|
||
def getChars(self, srcBegin, srcEnd, dst, dstBegin):
|
||
for i in range(srcBegin, srcEnd):
|
||
dst[dstBegin + i - srcBegin] = self._buf[i]
|
||
|
||
def codePointAt(self, index):
|
||
return ord(self._buf[index])
|
||
|
||
def codePointBefore(self, index):
|
||
return ord(self._buf[index - 1])
|
||
|
||
def codePointCount(self, beginIndex, endIndex):
|
||
return endIndex - beginIndex
|
||
|
||
|
||
class StringBuffer(StringBuilder):
|
||
"""java.lang.StringBuffer — 线程安全的可变字符序列"""
|
||
pass
|
||
|
||
|
||
class Class(Stub):
|
||
"""java.lang.Class"""
|
||
def __init__(self, cls):
|
||
super().__init__()
|
||
self._cls = cls
|
||
def getName(self): return self._cls.__name__
|
||
def getSimpleName(self): return self._cls.__name__
|
||
def getCanonicalName(self): return self._cls.__name__
|
||
def isInterface(self): return isinstance(self._cls, type)
|
||
def isArray(self): return self._cls is list
|
||
def isPrimitive(self): return self._cls in (int, float, bool, str, bytes)
|
||
def getSuperclass(self): return Class(self._cls.__base__) if self._cls.__base__ else None
|
||
def cast(self, obj): return obj
|
||
|
||
|
||
class Void(Stub):
|
||
"""java.lang.Void"""
|
||
TYPE = None
|
||
|
||
|
||
class VoidType(Stub):
|
||
"""java.lang.Void (inner type)"""
|
||
pass
|
||
|
||
|
||
# 注解类
|
||
class SuppressWarnings(Stub):
|
||
pass
|
||
class Deprecated(Stub):
|
||
pass
|
||
class Override(Stub):
|
||
pass
|
||
class FunctionalInterface(Stub):
|
||
pass |