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生成、计数器等场景中应用广泛。

powered by Gitbook© 2025 编外计划 | 最后修改: 2025-07-28 16:25:54

results matching ""

    No results matching ""