long 关键字
概述
long
是Java中的基本数据类型,表示64位有符号整数,取值范围为-9,223,372,036,854,775,808到9,223,372,036,854,775,807。
语法格式
long variableName; // 声明long变量
long variableName = value; // 声明并初始化
long variableName = 100L; // 长整型字面量
基本特性
public class LongBasicsExample {
public static void main(String[] args) {
// 基本声明和初始化
long l1 = 100;
long l2 = -500L; // 建议使用L后缀
long l3 = 9223372036854775807L; // 最大值
long l4 = -9223372036854775808L; // 最小值
System.out.println("l1 = " + l1);
System.out.println("l2 = " + l2);
System.out.println("l3 = " + l3);
System.out.println("l4 = " + l4);
// 常量值
System.out.println("long最小值: " + Long.MIN_VALUE);
System.out.println("long最大值: " + Long.MAX_VALUE);
System.out.println("long大小(位): " + Long.SIZE);
System.out.println("long大小(字节): " + (Long.SIZE / 8));
// 大数值表示
long million = 1_000_000L; // 使用下划线提高可读性
long billion = 1_000_000_000L;
long trillion = 1_000_000_000_000L;
System.out.println("百万: " + million);
System.out.println("十亿: " + billion);
System.out.println("万亿: " + trillion);
// 不同进制表示
long binary = 0b1010_1010L; // 二进制
long octal = 0777L; // 八进制
long hex = 0xFF_FF_FF_FFL; // 十六进制
System.out.println("二进制10101010: " + binary);
System.out.println("八进制777: " + octal);
System.out.println("十六进制FFFFFFFF: " + hex);
}
}
类型转换
public class LongConversionExample {
public static void main(String[] args) {
// 自动类型转换(向上转换)
byte b = 100;
short s = 1000;
int i = 100000;
long l1 = b; // byte -> long
long l2 = s; // short -> long
long l3 = i; // int -> long
System.out.println("byte到long: " + l1);
System.out.println("short到long: " + l2);
System.out.println("int到long: " + l3);
// long到浮点数
long largeLong = 123456789012345L;
float f = largeLong; // 可能丢失精度
double d = largeLong; // 精度更高
System.out.println("原始long: " + largeLong);
System.out.println("转为float: " + f);
System.out.println("转为double: " + d);
// 强制类型转换(向下转换)
long largeValue = 2147483648L; // 超过int最大值
int intFromLong = (int) largeValue; // 溢出
System.out.println("long转int(溢出): " + intFromLong);
// 安全转换检查
long value = 100000L;
if (value >= Integer.MIN_VALUE && value <= Integer.MAX_VALUE) {
int safeInt = (int) value;
System.out.println("安全转换为int: " + safeInt);
} else {
System.out.println("值超出int范围: " + value);
}
// 字符串转换
String str = "9876543210";
long longFromString = Long.parseLong(str);
System.out.println("字符串转long: " + longFromString);
// long转字符串
long l4 = 1234567890123L;
String stringFromLong = Long.toString(l4);
System.out.println("long转字符串: " + stringFromLong);
// 不同进制解析
long fromBinary = Long.parseLong("1010", 2);
long fromOctal = Long.parseLong("777", 8);
long fromHex = Long.parseLong("FF", 16);
System.out.println("二进制1010: " + fromBinary);
System.out.println("八进制777: " + fromOctal);
System.out.println("十六进制FF: " + fromHex);
}
}
大数运算
public class LongMathExample {
public static void main(String[] args) {
// 基本算术运算
long a = 1000000000000L;
long b = 2000000000000L;
System.out.println("加法: " + (a + b));
System.out.println("减法: " + (a - b));
System.out.println("乘法: " + (a * b));
System.out.println("除法: " + (b / a));
System.out.println("求余: " + (b % a));
// 检查溢出
long max = Long.MAX_VALUE;
System.out.println("最大值: " + max);
try {
long overflow = Math.addExact(max, 1); // 抛出异常
} catch (ArithmeticException e) {
System.out.println("加法溢出: " + e.getMessage());
}
try {
long overflow = Math.multiplyExact(max, 2); // 抛出异常
} catch (ArithmeticException e) {
System.out.println("乘法溢出: " + e.getMessage());
}
// 位运算
long x = 0xFF00FF00FF00FF00L;
long y = 0x0F0F0F0F0F0F0F0FL;
System.out.printf("x = 0x%016X%n", x);
System.out.printf("y = 0x%016X%n", y);
System.out.printf("x & y = 0x%016X%n", x & y);
System.out.printf("x | y = 0x%016X%n", x | y);
System.out.printf("x ^ y = 0x%016X%n", x ^ y);
System.out.printf("~x = 0x%016X%n", ~x);
// 位移运算
long value = 1L;
System.out.println("1左移32位: " + (value << 32));
System.out.println("1左移63位: " + (value << 63));
long negative = -8L;
System.out.println("-8右移2位: " + (negative >> 2)); // 算术右移
System.out.println("-8无符号右移2位: " + (negative >>> 2)); // 逻辑右移
}
}
时间和日期处理
import java.time.*;
import java.util.Date;
public class LongTimeExample {
public static void main(String[] args) {
// Unix时间戳(毫秒)
long currentTimeMillis = System.currentTimeMillis();
System.out.println("当前时间戳(毫秒): " + currentTimeMillis);
// 创建Date对象
Date date = new Date(currentTimeMillis);
System.out.println("当前时间: " + date);
// 时间计算
long oneDay = 24 * 60 * 60 * 1000L; // 一天的毫秒数
long oneWeek = 7 * oneDay; // 一周的毫秒数
long oneYear = 365 * oneDay; // 一年的毫秒数(近似)
System.out.println("一天毫秒数: " + oneDay);
System.out.println("一周毫秒数: " + oneWeek);
System.out.println("一年毫秒数: " + oneYear);
// 时间差计算
long startTime = System.currentTimeMillis();
// 模拟一些操作
try {
Thread.sleep(100); // 休眠100毫秒
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
long endTime = System.currentTimeMillis();
long duration = endTime - startTime;
System.out.println("操作耗时: " + duration + " 毫秒");
// 纳秒精度时间
long nanoTime1 = System.nanoTime();
// 一些计算
long sum = 0;
for (int i = 0; i < 1000000; i++) {
sum += i;
}
long nanoTime2 = System.nanoTime();
long nanosDuration = nanoTime2 - nanoTime1;
System.out.println("循环计算耗时: " + nanosDuration + " 纳秒");
System.out.println("转换为毫秒: " + (nanosDuration / 1_000_000.0) + " 毫秒");
// Java 8+ 时间API
Instant instant = Instant.ofEpochMilli(currentTimeMillis);
System.out.println("Instant: " + instant);
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
System.out.println("LocalDateTime: " + localDateTime);
}
}
文件大小和内存处理
import java.io.File;
import java.text.DecimalFormat;
public class LongFileSizeExample {
// 文件大小格式化
public static String formatFileSize(long bytes) {
if (bytes < 1024) {
return bytes + " B";
}
String[] units = {"B", "KB", "MB", "GB", "TB", "PB"};
int unitIndex = 0;
double size = bytes;
while (size >= 1024 && unitIndex < units.length - 1) {
size /= 1024;
unitIndex++;
}
DecimalFormat df = new DecimalFormat("#.##");
return df.format(size) + " " + units[unitIndex];
}
// 计算目录大小
public static long calculateDirectorySize(File directory) {
long size = 0;
if (directory.exists() && directory.isDirectory()) {
File[] files = directory.listFiles();
if (files != null) {
for (File file : files) {
if (file.isFile()) {
size += file.length();
} else if (file.isDirectory()) {
size += calculateDirectorySize(file); // 递归
}
}
}
}
return size;
}
// 内存信息
public static void printMemoryInfo() {
Runtime runtime = Runtime.getRuntime();
long maxMemory = runtime.maxMemory(); // 最大可用内存
long totalMemory = runtime.totalMemory(); // 当前分配内存
long freeMemory = runtime.freeMemory(); // 空闲内存
long usedMemory = totalMemory - freeMemory; // 已使用内存
System.out.println("内存信息:");
System.out.println(" 最大内存: " + formatFileSize(maxMemory));
System.out.println(" 分配内存: " + formatFileSize(totalMemory));
System.out.println(" 空闲内存: " + formatFileSize(freeMemory));
System.out.println(" 已用内存: " + formatFileSize(usedMemory));
double memoryUsage = (double) usedMemory / totalMemory * 100;
System.out.printf(" 内存使用率: %.1f%%%n", memoryUsage);
}
public static void main(String[] args) {
// 文件大小示例
long[] fileSizes = {
1023L, // 1023 B
1024L, // 1 KB
1048576L, // 1 MB
1073741824L, // 1 GB
1099511627776L, // 1 TB
};
System.out.println("文件大小格式化:");
for (long size : fileSizes) {
System.out.println(" " + size + " 字节 = " + formatFileSize(size));
}
// 内存信息
System.out.println();
printMemoryInfo();
// 大数据量计算
System.out.println("\n大数据计算:");
long itemCount = 1_000_000_000L; // 10亿条记录
long itemSize = 100L; // 每条记录100字节
long totalSize = itemCount * itemSize;
System.out.println("记录数量: " + String.format("%,d", itemCount));
System.out.println("每条大小: " + itemSize + " 字节");
System.out.println("总大小: " + formatFileSize(totalSize));
}
}
高精度ID生成
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.ThreadLocalRandom;
public class LongIdGeneratorExample {
// 简单的ID生成器
private static final AtomicLong counter = new AtomicLong(0);
// 雪花算法的简化版本
private static final long EPOCH = 1609459200000L; // 2021-01-01 00:00:00 UTC
private static final long MACHINE_ID_BITS = 5L;
private static final long SEQUENCE_BITS = 12L;
private static final long MAX_MACHINE_ID = (1L << MACHINE_ID_BITS) - 1;
private static final long MAX_SEQUENCE = (1L << SEQUENCE_BITS) - 1;
private static final long MACHINE_ID_SHIFT = SEQUENCE_BITS;
private static final long TIMESTAMP_SHIFT = SEQUENCE_BITS + MACHINE_ID_BITS;
private final long machineId;
private long lastTimestamp = -1L;
private long sequence = 0L;
public LongIdGeneratorExample(long machineId) {
if (machineId > MAX_MACHINE_ID || machineId < 0) {
throw new IllegalArgumentException("机器ID超出范围");
}
this.machineId = machineId;
}
// 生成简单递增ID
public static long getNextSimpleId() {
return counter.incrementAndGet();
}
// 生成时间戳ID
public static long getTimestampId() {
return System.currentTimeMillis();
}
// 生成随机ID
public static long getRandomId() {
return ThreadLocalRandom.current().nextLong(Long.MAX_VALUE);
}
// 雪花算法ID生成
public synchronized long getNextSnowflakeId() {
long timestamp = System.currentTimeMillis();
if (timestamp < lastTimestamp) {
throw new RuntimeException("时钟回拨,拒绝生成ID");
}
if (timestamp == lastTimestamp) {
sequence = (sequence + 1) & MAX_SEQUENCE;
if (sequence == 0) {
// 序列号用完,等待下一毫秒
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = timestamp;
return ((timestamp - EPOCH) << TIMESTAMP_SHIFT) |
(machineId << MACHINE_ID_SHIFT) |
sequence;
}
private long tilNextMillis(long lastTimestamp) {
long timestamp = System.currentTimeMillis();
while (timestamp <= lastTimestamp) {
timestamp = System.currentTimeMillis();
}
return timestamp;
}
// 解析雪花ID
public static void parseSnowflakeId(long id) {
long timestamp = (id >> TIMESTAMP_SHIFT) + EPOCH;
long machineId = (id >> MACHINE_ID_SHIFT) & MAX_MACHINE_ID;
long sequence = id & MAX_SEQUENCE;
System.out.println("雪花ID解析:");
System.out.println(" ID: " + id);
System.out.println(" 时间戳: " + timestamp + " (" + new java.util.Date(timestamp) + ")");
System.out.println(" 机器ID: " + machineId);
System.out.println(" 序列号: " + sequence);
}
public static void main(String[] args) {
System.out.println("=== ID生成示例 ===");
// 简单递增ID
System.out.println("递增ID:");
for (int i = 0; i < 5; i++) {
System.out.println(" " + getNextSimpleId());
}
// 时间戳ID
System.out.println("\n时间戳ID:");
for (int i = 0; i < 3; i++) {
System.out.println(" " + getTimestampId());
try {
Thread.sleep(1); // 确保时间戳不同
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
// 随机ID
System.out.println("\n随机ID:");
for (int i = 0; i < 3; i++) {
System.out.println(" " + getRandomId());
}
// 雪花算法ID
System.out.println("\n雪花算法ID:");
LongIdGeneratorExample generator = new LongIdGeneratorExample(1);
for (int i = 0; i < 3; i++) {
long snowflakeId = generator.getNextSnowflakeId();
System.out.println(" " + snowflakeId);
}
// 解析雪花ID
System.out.println();
long sampleId = generator.getNextSnowflakeId();
parseSnowflakeId(sampleId);
}
}
最佳实践
public class LongBestPractices {
// 1. 使用L后缀明确表示long字面量
public static void literalSuffix() {
long good = 1000000000L; // 推荐:明确使用L后缀
long bad = 1000000000; // 可以,但不够明确
// 大数值更需要L后缀
long large = 3000000000L; // 必须使用L,否则编译错误
}
// 2. 安全的数学运算
public static long safeAdd(long a, long b) {
try {
return Math.addExact(a, b);
} catch (ArithmeticException e) {
System.err.println("加法溢出: " + a + " + " + b);
return Long.MAX_VALUE; // 或者抛出自定义异常
}
}
public static long safeMultiply(long a, long b) {
try {
return Math.multiplyExact(a, b);
} catch (ArithmeticException e) {
System.err.println("乘法溢出: " + a + " * " + b);
return Long.MAX_VALUE;
}
}
// 3. 时间间隔计算
public static String formatDuration(long millis) {
long seconds = millis / 1000;
long minutes = seconds / 60;
long hours = minutes / 60;
long days = hours / 24;
if (days > 0) {
return days + "天 " + (hours % 24) + "小时";
} else if (hours > 0) {
return hours + "小时 " + (minutes % 60) + "分钟";
} else if (minutes > 0) {
return minutes + "分钟 " + (seconds % 60) + "秒";
} else {
return seconds + "秒 " + (millis % 1000) + "毫秒";
}
}
// 4. 范围验证
public static boolean isValidTimestamp(long timestamp) {
long now = System.currentTimeMillis();
long oneYearAgo = now - (365L * 24 * 60 * 60 * 1000);
long oneYearLater = now + (365L * 24 * 60 * 60 * 1000);
return timestamp >= oneYearAgo && timestamp <= oneYearLater;
}
// 5. 内存友好的long数组处理
public static void processLargeLongArray(long[] array) {
// 分批处理大数组,避免内存压力
int batchSize = 10000;
for (int start = 0; start < array.length; start += batchSize) {
int end = Math.min(start + batchSize, array.length);
// 处理当前批次
long sum = 0;
for (int i = start; i < end; i++) {
sum += array[i];
}
System.out.println("批次 " + (start / batchSize + 1) +
" 处理了 " + (end - start) + " 个元素,和为: " + sum);
}
}
public static void main(String[] args) {
System.out.println("=== 安全数学运算 ===");
System.out.println("安全加法: " + safeAdd(Long.MAX_VALUE - 1, 1));
System.out.println("溢出加法: " + safeAdd(Long.MAX_VALUE, 1));
System.out.println("\n=== 时间格式化 ===");
long[] durations = {1500L, 75000L, 3675000L, 90061000L, 172861000L};
for (long duration : durations) {
System.out.println(duration + "ms = " + formatDuration(duration));
}
System.out.println("\n=== 时间戳验证 ===");
long now = System.currentTimeMillis();
long[] timestamps = {now, now - 400L * 24 * 60 * 60 * 1000, 0L, now + 1000L};
for (long timestamp : timestamps) {
System.out.println("时间戳 " + timestamp + " 有效: " + isValidTimestamp(timestamp));
}
System.out.println("\n=== 数组批处理 ===");
long[] largeArray = new long[25000];
for (int i = 0; i < largeArray.length; i++) {
largeArray[i] = i + 1;
}
processLargeLongArray(largeArray);
}
}
long类型是Java中处理大整数的主要数据类型,在时间处理、文件大小、ID生成、计数器等场景中应用广泛。