编译时不好的注释会让代码丢失并产生问题

  

写在之前

这篇文章是上一篇文章的后续事件,记录的事情也挺有意思。想看事情如何开始的点击链接

频繁GC引起卡顿问题排查与解决


进入正题

不知道有没有人遇到过编译后部分代码缺失呢?反正我遇到了, 上一篇文章提到了因为开发人员写了死循环造成系统卡死。问题代码如下,此方法缺少tempStart.add(calendarField, 1)变成了死循环

    --startTime1开始时间
    --endTime1 截止时间
    --开发人员写了一个方法获取两个时间的中间天数 - -# 大致代码如下
    SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
    int calendarField=Calendar.DAY_OF_MONTH;
    Calendar tempStart = Calendar.getInstance();
	tempStart.setTime(startTime1);
	while (endTime1.getTime() >= startTime1.getTime()) {
		dateList.add(format.format(startTime1));
		tempStart.add(calendarField, 1);  //没有此行时候死循环
		startTime1 = tempStart.getTime();
    }

起初,我以为本事故只是开发人员漏提交了代码引起的偶然事情,然而并不是如此。 我再三确认代码库里已经提交了tempStart.add(calendarField, 1) 并非死循环后重新构建并请测试组继续验证。结果同样的问题又出现了。使用Arthas反编译后发现又是之前的问题,因缺少tempStart.add(calendarField, 1)造成死循环。


/*274*/         Calendar tempStart = Calendar.getInstance();
/*275*/         tempStart.setTime(startTime1);
                while (endTime1.getTime() >= startTime1.getTime()) {
/*277*/             dateList.add(format.format(startTime1));
/*279*/             startTime1 = tempStart.getTime();
                }

经过反复确认测试环境使用的包无问题,甚至自己重新使用jenkins构建并反编译确认。结果:代码库里有tempStart.add(calendarField, 1)代码, 但是构建后的程序包反编译没有tempStart.add(calendarField, 1)。 这种诡异事情还真我遇到了

提交的代码

 编译后的代码

世界真精彩!

我开始以为是编译问题,此工程编译使用的是1.6,我写了一个测试类来验证我的想法,参考代码如下

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class Test1 {
	public static void main(String[] args) {
		try {
			List<String> dateList = new ArrayList<String>();
			SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
			int calendarField=Calendar.DAY_OF_MONTH;
			
			String startTime = "20230420";
			String endTime = "2023042601";
			Date startTime1 = format.parse(startTime);
			Date endTime1 = format.parse(endTime.substring(0,startTime.length()));
			Calendar tempStart = Calendar.getInstance();
			tempStart.setTime(startTime1);
			System.out.println("first"+startTime1);
			while (endTime1.getTime() >= startTime1.getTime()) {
				dateList.add(format.format(startTime1));
				tempStart.add(calendarField, 1);
				startTime1 = tempStart.getTime();
			}
		} catch (Exception e) {
//	        log.error(e);
		}
	}
}

分别使用1.6和1.8和17编译

D:\>javac Test1.java

D:\>

编译后反编译class发现1.6,1.8,17处理结果相同,而 localCalendar.add(i, 1)代码正常

public class Test1
{
  public static void main(String[] paramArrayOfString)
  {
    try
    {
      java.util.ArrayList localArrayList = new java.util.ArrayList();
      java.text.SimpleDateFormat localSimpleDateFormat = new java.text.SimpleDateFormat("yyyyMMdd");
      int i = 5;
      
      String str1 = "20230420";
      String str2 = "2023042601";
      java.util.Date localDate1 = localSimpleDateFormat.parse(str1);
      java.util.Date localDate2 = localSimpleDateFormat.parse(str2.substring(0, str1.length()));
      java.util.Calendar localCalendar = java.util.Calendar.getInstance();
      localCalendar.setTime(localDate1);
      System.out.println("first" + localDate1);
      while (localDate2.getTime() >= localDate1.getTime()) {
        localArrayList.add(localSimpleDateFormat.format(localDate1));
        localCalendar.add(i, 1);
        localDate1 = localCalendar.getTime();
      }
    }
    catch (Exception localException) {}
  }
}

从网上也搜了搜,但没有同学遇到类似问题,也没有相应的文章。还好在排查问题过程中发现java类提交的时候使用的是utf-8  ,我就怀疑是不是编码格式问题, 从代码库里拷贝出问题源文件,然后修改成测试类,下载后发现因为java类是UTF-8提交的代码。中文已经变成了乱码

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class Test {
	public static void main(String[] args) {
		try {
			List<String> dateList = new ArrayList<String>();
			SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
			int calendarField=Calendar.DAY_OF_MONTH;
			
			String startTime = "20230420";
			String endTime = "2023042601";
			Date startTime1 = format.parse(startTime);
			Date endTime1 = format.parse(endTime.substring(0,startTime.length()));
			Calendar tempStart = Calendar.getInstance();
			tempStart.setTime(startTime1);
			System.out.println("first"+startTime1);
			while (endTime1.getTime() >= startTime1.getTime()) {
				dateList.add(format.format(startTime1));
				//鏈夊绉嶆ā寮忓彲浠ュ鍔犳垨鍑忓幓鐩稿簲鐨勬椂闂�
				tempStart.add(calendarField, 1);
				startTime1 = tempStart.getTime();
			}
		} catch (Exception e) {
//	        log.error(e);
		}
	}
}

编译测试时发现编译警告,并且在警告后有丢失的代码信息。如下

D:\>javac Test.java
Test.java:28: 警告:编码 GBK 的不可映射字符
 //閺堝顧嬬粔宥喣佸蹇撳讲娴犮儱顤冮崝鐘冲灗閸戝繐骞撻惄绋跨安閻ㄥ嫭妞傞梻锟? tempStart.add(calendarField, 1);
                                                                        ^
1 警告

再将Test.class反编译,发现tempStart.add(calendarField, 1)这条命令丢失了

从现象上看乱码后的1行代码被当做了乱码信息

package com.star.sms.business.customer.job;

import java.io.PrintStream;
import java.util.List;

public class Test
{
  public static void main(String[] paramArrayOfString)
  {
    try
    {
      java.util.ArrayList localArrayList = new java.util.ArrayList();
      java.text.SimpleDateFormat localSimpleDateFormat = new java.text.SimpleDateFormat("yyyyMMdd");
      int i = 5;
      
      String str1 = "20230420";
      String str2 = "2023042601";
      java.util.Date localDate1 = localSimpleDateFormat.parse(str1);
      java.util.Date localDate2 = localSimpleDateFormat.parse(str2.substring(0, str1.length()));
      java.util.Calendar localCalendar = java.util.Calendar.getInstance();
      localCalendar.setTime(localDate1);
      System.out.println("first" + localDate1);
      while (localDate2.getTime() >= localDate1.getTime()) {
        localArrayList.add(localSimpleDateFormat.format(localDate1));
        
        localDate1 = localCalendar.getTime();
      }
    }
    catch (Exception localException) {}
  }
}

故事结尾

本问题是由于注释乱码引起了编译错误,开发过程中以下两点十分重要

1)开发人员都希望别人多写注释,那么自己写注释时,必须注意乱码问题

2)特殊符号使用国际化文件,这样可以有效的避免乱码


上一篇:频繁GC引起卡顿问题排查与解决

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

=PNZ=BeijingL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值