• java中string长度有限制吗,最大是多少?


    这个问题其实还是有必要去谈一谈的,在我们进行字符串赋值的时候一般不会注意到string的长度什么的,因为一般达不到,但是有个特殊的字符串比较长,那就是Base64转码;

    base64是进行图片传输的时候特殊的编码方式,这个字符就很长,超过了string的“编译时”接收最大长度。为什么说是编译时呢?带着问题我们走入今天的主题!

    首先要知道String的长度限制我们就需要知道String是怎么存储字符串的,String其实是使用的一个char类型的数组来存储字符串中的字符的。
    在这里插入图片描述那么String既然是数组存储那数组会有长度的限制吗?是的有限制,但是是在有先提条件下的,我们看看String中返回length的方法
    在这里插入图片描述
    整数在java中是有限制的,我们通过源码来看看int类型对应的包装类Integer可以看到,其长度最大限制为2^31 -1,那么说明了数组的长度是0~231-1,那么计算一下就是(231-1 = 2147483647 = 4GB)
    在这里插入图片描述
    Integer的取值范围

    看到这我们尝试通过编码来验证一下上述观点。
    在这里插入图片描述以上是我通过定义字面量的形式构造的10万个字符的字符串,编译之后虚拟机提示报错,说我们的字符串长度过长,不是说好了可以存21亿个吗?为什么才10万个就报错了呢?

    其实这里涉及到了JVM编译规范的限制了,其实JVM在编译时,如果我们将字符串定义成了字面量的形式,编译时JVM是会将其存放在常量池中,这时候JVM对这个常量池存储String类型做出了限制,

    至于关于JVM的那块我就不做赘述了,放在文末的原文里了,感兴趣的读者可以看看

    问:字符串有长度限制吗?是多少?

    答:首先字符串的内容是由一个字符数组 char[] 来存储的,由于数组的长度及索引是整数,且String类中返回字符串长度的方法length() 的返回值也是int ,所以通过查看java源码中的类Integer我们可以看到Integer的最大范围是2^31 -1,由于数组是从0开始的,所以数组的最大长度可以使【0~2^31-1】通过计算是大概4GB。

    但是通过翻阅java虚拟机手册对class文件格式的定义以及常量池中对String类型的结构体定义我们可以知道对于索引定义了u2,就是无符号占2个字节,2个字节可以表示的最大范围是2^16 -1 = 65535。其实是65535,但是由于JVM需要有一个结束指令,所以这个范围就为65534了。超出这个范围在编译时期是会报错的,但是运行时拼接或者赋值的话范围是在整形的最大范围。

    这里附上一个通过base64进行加密解密的操作:
    百度里在线base64图片转码:
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/d73a742a1fbf4b7fbe5da2a3139da660.png

    解码操作:

    protected static String generateImage(String imgStr, String path) throws IOException {
        // data:image/jpeg;base64,
        int start = imgStr.indexOf("/");
        int end = imgStr.indexOf(";");
        String ext = "." + imgStr.substring(start + 1, end);
        imgStr = imgStr.substring(imgStr.indexOf(",") + 1);
    
        // Base64解码
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] b = decoder.decodeBuffer(imgStr);
        for (int i = 0; i < b.length; ++i) {
            if (b[i] < 0) {
                b[i] += 256;
            }
        }
    
        // 存放位置,文件夹按日期区分
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        SimpleDateFormat fileSdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        String time = sdf.format(new Date());
        String fileName = fileSdf.format(new Date()) + ext;
        File file = new File("C:/file_upload/" + path + time);
        if(!file.exists()){
            file.mkdirs();
        }
        OutputStream out = new FileOutputStream(file + "/" + fileName);
        out.write(b);
        out.flush();
        out.close();
        String photo_address = path + time + "/" + fileName;
        return photo_address;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    加密操作:

    protected String getImageStr(String filePath) {
        InputStream inputStream = null;
        byte[] data = null;
        try {
            inputStream = new FileInputStream(filePath);
            data = new byte[inputStream.available()];
            inputStream.read(data);
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 加密
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(data);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    我之前做的没有上述的那样拆分,直接就是通过substring(22)拿掉了前面的22位(我的是png,注意这个位数,有的是jpeg就是23.)
    附上我自己项目里的代码

     public static boolean generateImage(String imgStr, String filePath, String fileName) {
            try {
                if (imgStr == null) {
                    return false;
                }
                /*
                * Base64 要求把每三个8Bit 的字节转换为四个6Bit 的字节(3*8 = 4*6 = 24 ),然后把6Bit 再添两位高位0 ,
                * 组成四个8Bit 的字节,也就是说,转换后的字符串理论上将要比原来的长1/3 。
                * */
                BASE64Decoder decoder = new BASE64Decoder();
                byte[] b = decoder.decodeBuffer(imgStr);
                File file = new File(filePath);
                if (!file.exists()) {
                    file.mkdirs();
                }
                OutputStream out = new FileOutputStream(filePath+fileName);
                out.write(b);
                out.flush();
                out.close();
                return true;
            } catch (Exception e) {
                return false;
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    参考文章:
    面试官:String长度有限制吗?是多少?还好我看过

    【Java】# Java对图片进行base64编解码

  • 相关阅读:
    (十一)【Jmeter】线程(Threads(Users))之jp@gc-Ultimate Thread Group
    身为程序员,你很有必要了解一下JNPF
    内联函数、带默认形参值的函数、引用传参以及函数重载的具体介绍和例子
    Opencascade常用函数 更新中...
    [极客大挑战 2019]RCE ME
    汽车零部件企业信邦控股之项目管理实践案例
    pytorch之文本篇项目——聊天机器人(一)数据预处理
    9月11日,每日信息差
    【人工智能时代的刑法体系与责任主体概述】
    论文笔记 A Comprehensive Survey on Graph Neural Networks(GNN综述)
  • 原文地址:https://blog.csdn.net/delete_bug/article/details/126199525