当前位置: 首页 > 网络应用技术

Java代码优化的30个提示

时间:2023-03-08 18:30:45 网络应用技术

  我在有关优化相关问题之前写了两个问题:“谈论SQL优化的15个技巧”和“ 11个用于优化接口性能的技巧”。出版后,网络在整个网络上都受到了广泛的欢迎。阅读和赞美很高,这表明了此类文章的价值。

  今天,我们将优化此主题。让我们一起谈谈Java中的30条代码优化技巧,希望为您提供帮助。

  我不知道您是否有缝制的字符串字符串,尤其是有多个参数并且字符串相对较长的情况。

  例如,现在有一个需求:用GET请求调用第三方接口,并且您需要在URL之后缝制多个参数。

  过去,我们的请求地址是这样缝制的:

  该字符串使用数字缝合,这很容易犯错。

  稍后优化后,切换到缝线字符串的使用:

  优化代码后,我们有一些模拟。

  但是它看起来仍然很尴尬。

  目前,它可以优化:

  代码的可读性突然提高了很多。

  我们通常可以使用方法来缝制URL请求参数,日志打印和其他字符串。

  但是,不建议在for循环中使用其缝合字符串,因为其执行效率比使用+数字缝合字符串或使用StringBuilder缝合字符串慢。

  大概每个人都使用了很多。我们通常需要将数据从文件或数据中输入数据,甚至从目录B到目录C的文件A,甚至是文件A。

  JDK为我们提供了一个非常丰富的API,可以操作IO流。

  例如:

  此示例的主要功能是将1.TXT文件中的内容复制到2.TXT文件。此示例还可以从普通IO流的角度满足需求,但是性能不好。

  因为在此示例中,当从1.TXT文件中读取数据字节时,您将立即编写2.TXT文件,并且需要经常读取和写文件。

  优化:

  此示例使用并创建了输入输出流。

  最关键的部分是定义一个缓冲区字节数组,暂时保留从1.TXT文件中读取的数据,然后将Buffer Byte数组的数据一次写入2.TXT。

  这样做的优点是减少读写文件的数量,我们都知道阅读和编写文件是非常耗时的操作。换句话说,缓存输入输出流的使用可以改善IO的性能,尤其是当文件很大时,效率将大大提高。

  在我们的日常开发中,循环收集是必不可少的操作。

  但是,如果循环水平更深并且周期在周期中循环,则可能会影响代码的执行效率。

  这

  在此示例中,有两层周期。如果有更多的用户列表和Rolelist数据,则需要多次遍历我们需要的数据,这会大大消耗CPU资源。

  这

  减少周期数的最简单方法是将第二层环的集合变成,以便您可以直接传递并获取所需的数据。

  尽管MAP的密钥存在,但遍历数据或或或或或或或多数。

  在我们的日常开发中,我们可能会经常访问,例如获得数据库连接,读取文件等。

  我们以数据库连接为例。

  这

  以上代码可以正常运行,但是它犯了一个大错误,即:Resultset,AppardStatement和Connection对象。使用后,它没有关闭。

  我们都知道数据库连接是一个非常有价值的资源。我们不能总是创建连接,并且在使用后,我们不会恢复和浪费数据库资源。

  这

  在此示例中,无论是结果集还是准备安排还是连接对象,该方法将调用该方法关闭资源。

  这里有一个温暖的提醒:结果集或准备序列或连接对象,这三个人中三个人的顺序无法逆转,否则可能会有异常。

  我们都知道,从数据库中检查数据必须首先连接数据库并获得资源。

  如果要实现程序多线程,则需要使用类创建线程。线程也是资源。

  数据库操作的过程通常是这样的:

  连接和关闭连接的创建是一个非常耗时的操作。创建连接需要同时创建一些资源。关闭连接时,需要恢复这些资源。

  如果用户的每个数据库请求,程序需要创建连接和关闭连接,则可能会浪费很多时间。

  另外,可能导致太多数据库连接。

  我们都知道数据库是有限的。以MySQL为例,最大连接数为:,但是您可以通过参数调整数字。

  如果用户请求的连接数量超过最大连接数,则将报告:abnormal。如果有新的请求,您会发现数据库不可用。

  目前,您可以通过命令:

  查看最大连接数。

  然后通过命令:

  手动修改最大连接数。

  这种方法只能暂时缓解问题。这不是一个好的解决方案,无法从根本上解决问题。

  最大的问题是,数据库连接的数量可以无限期地增加而无需控制。

  目前,我们可以使用它。

  目前,Java开源数据库连接池是:

  最常用的数据库连接池是:。

  我们都知道,通过创建对象实例,它比使用关键字要慢得多。

  因此,不建议每次使用用户请求时创建实例。

  有时,为了灵活性,我必须反映创建实例。我目前该怎么办?

  答:添加。

  实际上,春季使用了大量反射。我们以付款方式为例。

  根据不同付款代码的前端,动态找到相应的付款方式并启动付款。

  我们首先定义注释。

  将此注释添加到所有付款课程中

  然后添加最关键的类别:

  PayService2类实现接口,以便可以以这种方式获得的实例。这一步骤实际上是弹簧容器启动的时候,通过反射来处理弹簧。

  我们得到了付款码注释的课程。在一个中,地图中的值是工资码注释中定义的值。它与代码参数一致。值是付款类的实例。

  这样,每次您可以直接通过代码获得付款实例,而无需...否则法官。如果要添加新的付款方式,则只需要使用付款码注释即可在付款中定义新代码班级。

  注意:以这种方式代码没有业务含义,只要不重复,它就可以是纯数字。

  很多时候,我们需要在某个接口中调用其他服务的接口。

  例如,有这样的业务场景:

  用户信息查询接口需要返回:用户名,性别,级别,头像,点,增长价值和其他信息。

  用户名,性别,等级和头像在用户服务中。积分在整体服务中,增长价值在增长价值服务中。为了总结这些数据以均匀返回,需要提供另一种外部接口服务。

  因此,用户信息查询接口需要调用用户查询接口,点查询接口和增长值查询接口,然后汇总数据以均匀返回。

  呼叫过程如下图所示:远程接口的总时间消耗为530ms = 200ms + 150ms + 150ms + 180ms

  显然,这种串行调用远程接口性能非常糟糕。调用远程接口消耗的总时间是所有远程接口时间的总和。

  那么如何优化远程接口的性能?

  如上所述,由于串行调用多个远程接口很差,为什么不更改为平行?

  如下图所示:调用远程接口200ms = 200ms的总时间消耗(即最长的远程接口调用)

  在Java8之前,您可以通过实现接口获得线程结果。

  此函数是通过Java8.LET以完整形式为例的类实现的:

  提醒一个温暖的提醒,不要忘记在这两种方法中使用线程池。在示例中,我使用执行程序指示自定义线程池。为了防止高汇编场景,线程太多。

  有时,创建对象是一个非常耗时的操作,尤其是在创建对象时,需要创建许多其他对象。

  我们以单个模式为例。

  当引入单身模式时,您必须首先介绍它的两种非常著名的实现方法:和。

  初始化时已经构建了实例。无论您是否使用它,首先构建它。特定代码如下:

  使用饥饿的han模式的优点是:,但是缺点也很明显。

  一开始,它是实例化的。如果制度化过程非常耗时,而没有使用最后一个对象,那不是浪费资源吗?

  真的。

  目前,您可能认为没有必要事先实例化对象。

  这是我接下来介绍的内容:。

  顾名思义,只有在使用实例时才在使用该实例时。“懒惰”是在使用时检查是否有任何示例。特定代码如下:

  该示例中的实例对象首先为空,呼叫方法调用getInstance方法将真正实例化。

  与饥饿的han模式相比,懒惰模式未提前实例化。它在真正使用时会立即实例化,实例化对象的效率更高。

  除了单个模式外,使用懒惰加载可能更有用:

  在实际的项目开发中,我们需要经常使用集合,例如arraylist,hashmap等。

  但是有一个问题:初始化集合时是否指定大小?

  这

  执行时间处理时间:

  如果初始化集合时指定大小。

  这

  执行时间处理时间:

  我们惊讶地发现,创建集合时规定了大小的大小,并且添加100,000个元素的效率比没有指定尺寸的效率翻了一番。

  如果您看到了源代码,您会发现其默认大小是,如果添加元素超过一定阈值,则将以两倍的大小扩展。

  如果您考虑一下,如果您安装了100,000个数据,则需要扩展多少次?每个扩展都需要不间断的复制元素,从旧系列到新系列,需要浪费多少时间。

  当我们开发界面时,如果我们出现,以便给用户一个更友好的提示,例如:

  如果您不进行任何处理,当我们询问添加接口时,执行结果直接报告错误:什么?用户可以直接看到错误消息吗?

  这种互动方式为用户带来了非常差的体验。为了解决此问题,我们通常在接口中捕获异常:

  转换界面后,出现异常时会提示:“数据异常”对用户更友好。

  看起来还不错,但是有问题。

  如果只是一个接口,但是如果项目中有数百个接口,您是否需要异常的捕获代码?

  答案是不。目前,全球异常治疗派上用场:

  只要在方法中处理异常情况,就可以自信地使用业务界面,并且不再需要异常(某人均匀处理)。这真的很弯曲。

  如果您读过JDK的源代码,例如:,等。您会发现使用它们的底层。

  为什么发展JDK的伟大神灵喜欢使用操作?

  答:因为位操作更有效。

  ThreadLocal的GET,设置,删除方法中有这样的代码行:

  使用键的hashCode值,阵列的长度将减少1.键是螺纹局部对象。阵列的长度减少了1,这等同于将阵列的长度除以1,然后。

  这是一种哈希算法。

  让我们给您一个示例:假设Len = 1String requestUrl =“ http://susan.sc.cn?username = %S&gage=%S&address=%S&roledid = %S”;字符串url = string.format(requesturl,用户名,年龄,地址,性别,性别,roledid);1,key.threadLocalHashCode = 31,

  因此:int i = 31&15 = 15

  它等同于:int i = 31%1String requestUrl =“ http://susan.sc.cn?username = %S&address=%S&sexs&sex =%s”;字符串url = string.format(requestUrll,usernameme,年龄,地址,性别,性别,roledid);1 = 15

  计算结果是相同的,但是使用效率较高。

  为什么计算更有效?

  答案:由于螺纹局部的初始大小是每次扩展双重范围,所以数组的大小一直是2的N前部。

  该数据具有高度为0的规则,低位置为1。当进行和计算时,您不需要考虑高级别,因为操作的结果必须为0。因此效率更高。

  在Java的巨大系统中,实际上有很多好的工具,这是我们通常所说的:

  如果在我们的日常工作中,我们可以使用该想法的快捷键来大大提高我们的发展效率。

  如果您介绍了POM文件,您将获得很多好工具。这里是收集工具的集合:。

  它太容易使用,让我喜欢它。

  如果您想将一个分为几个。

  我们以前这样做:

  将列表根据size = 2放入多个小集中,上面的代码看起来更麻烦。

  如果使用它,则可以像这样编写代码:

  结果:

  在此示例中,列表有5个数据。我将列表分为3页,并根据大小的大小转换为3个小收藏。

  这是我最喜欢的方法之一,经常用于项目。

  例如,有一个需求:现在有5,000个ID,您需要调用批处理用户查询界面并查找用户数据。但是,如果您直接检查5,000个用户,则单个接口的响应时间可能非常慢。是否更改了组件页面,每次仅检查500个用户,并且调用了10次异步的接口,并且单个接口的响应缓慢不会有问题。

  如果您知道更多且非常有用的第三方工具,则可以在我的文章“ Envolling Blood推荐17个车轮”中看到另一篇文章,以提高发展效率。

  在某些业务场景中,为了防止多个线程修改共享数据,引起了数据异常。

  为了求解并发场景,多个线程同时修改数据,从而导致数据不一致。通常,我们将:。

  但是,如果锁定不好,它也会非常影响接口性能。

  我们在Java中的代码锁提供了一个关键字。

  通常有两种写作方法:和谐。

  首先查看如何锁定该方法:

  在此处锁定的目的是防止在并发的情况下创建相同的目录,并且第二次将创建失败,从而影响业务功能。

  但是该方法中的这种锁定有点厚。因为dosave方法中的上传文件和消息无需锁定。只能通过创建目录方法锁定您可以锁定。

  我们都知道文件上传操作是非常耗时的。如果整个方法被锁定,那么您需要等到执行整个方法才能释放锁。这会导致这种方法的性能不佳,并且变得比彼此更加彼此。

  目前,我们可以将其更改为代码块,特定代码如下:

  转换后,锁的粒径突然变得更小,并且仅通过并发创建目录函数添加锁。创建目录是一个非常快速的操作,即使接口上锁的性能几乎没有效果。

  最重要的是,可以同时执行其他上传文件和发送消息。

  有许多技术可确保Java中的线程安全性。您可以将关键字与代码块相等。

  但是它们具有一个共同的功能,即锁会损失代码的性能。

  实际上,JDK:。

  没错,使用类是该想法的具体表现。

  ThreadLocal为使用变量的每个线程提供了一个自变量副本,因此每个线程可以独立更改其副本而不会影响与其他线程相对应的副本。

  ThreadLocal的用法大致是这样的:

  在业务代码的第一行中,将UserInfo对象设置为CurrentUser,因此在业务代码中,您可以通过CurrentUser.get()获得UserInfo对象,尤其是对于更深层次的业务代码级别调用,此用法非常有用,可以减少许多不必要的参数。

  但是,在较高的场景中,此代码存在问题,并且仅将数据存储到threadlocal,并且使用后未及时清洁数据。

  即使(弱参考),螺纹局部也可能存在问题,因为只有键(即螺纹局部对象)设置为弱参考,但值不设置为弱。

  那么,如何解决这个问题?

  您需要在代码块中调用无用的数据。

  我想知道您是否在项目中看到了它。有些同事是否与类型的两个参数相比?

  无论如何我已经看到了,这是对的吗?

  我的答案是查看特定情况,不能说是对还是错。

  某些状态字段,例如:orderstatus:-1(无命令),0(订单),1(付款),2(已完成),3(取消),5个州。

  如果您使用==判断您是否平等:

  返回结果是真的吗?

  答:错误。

  有些学生可能会驳斥,整数没有范围:缓存吗?

  为什么是错误的?

  让我们看一下整数的结构:

  它实际上没有使用。

  那么缓存在哪里使用?

  答案是在方法中:

  如果上述判断已更改为:

  返回结果是真的吗?

  答:正确是正确的。

  我们必须养成一个良好的代码习惯,尝试使用==来确定两个整数类型数据是否相等,并且仅在上面提到的非常特殊的情况下是相同的。

  相反,应该更改以判断:

  运行结果为真。

  很多时候,我们需要在日常开发中创建一个集合。例如:要进行性能注意事项,请查询数据库中表的所有数据,一次将其加载到内存集合中,然后进行业务逻辑。

  例如:

  一次从数据库中查询,然后在周期中进行每个用户的业务逻辑处理。

  如果数据量很大,则用户列表集合将非常大,这可能直接导致内存不足,并且整个应用程序将被挂起。

  对于这种情况,您必须这样做。

  例如:

  在上述分页转换之后,仅检查数据库中的记录并将其保存到UserList集合中,以使用户列表不会占用过多的内存。

  在这里明确解释的是,如果您查询的表中的数据量很小,则不会一次保存在内存中,并且不会占用过多的内存。可以在不进行分页的情况下执行这种情况。

  此外,还有特殊情况,也就是说,表中的记录数量不多,但是每个记录都有很多字段,并且单个记录占据了很多内存空间。在这个时间问题。

  总体原则是避免尽可能多地创建大型收藏,从而导致记忆不足的问题,但是大型收藏有多大。目前,没有唯一的测量标准,这需要对实际业务场景进行单独的分析。

  在我们的表中,有许多状态字段,例如:订单状态,禁用状态,删除状态等。

  每个状态都有多个值,代表不同的含义。

  例如,订单状态是:

  如果没有枚举,通常是这样做的:

  需要定义许多静态常数,其中包含不同的状态和状态。

  使用该定义后,代码如下:

  使用枚举转换后,他的职责更加单身。

  使用枚举的优点是:

  我不知道您是否在实际项目开发中使用了固定值?

  例如:

  或者:

  其中,它是一个固定值,每次都是相同的。

  由于它是固定值,为什么我们不将它们定义为静态常数?

  这更直观,方便统一的管理和维护以及更方便的代码重复使用。

  代码优化:

  或者:

  使用关键字修改静态常数,这意味着变量的含义,并且意味着它。

  将两个关键字添加在一起,并告诉Java虚拟机变量。内存中只有一个。它在全球情况下是独一无二的。它不能修改,也就是说。

  当许多朋友使用春季框架开发项目时,为了方便起见,他们喜欢使用注释来提供交易功能。

  是的,通过 @thransactional的注释提供交易功能,这确实可以编写更少的代码以提高发展效率。

  但这也很容易引起大事并引起其他问题。

  让我们拍照图片以查看由大事务引起的问题。从数字可以看出,大型交易的问题可能会导致接口超时并直接影响界面的性能。

  我们如何优化大事务?

  关于大型交易的问题,我的另一篇文章“如何解决头痛大交易问题?”,它在其中进行了非常详细的介绍。如果您有兴趣,可以看到它。

  当我们编写代码时,如果...其他的判断条件是必不可少的。不同的判断条件通常不同。

  胡说八道,首先查看以下代码。

  Payservice类的Topay方法主要是启动付款。基于不同的代码,决定以不同的付款类(例如Aliapay)来调用薪酬方法。

  这个代码怎么了?也许有些人这样做。

  想象一下,如果付款方式越来越多,例如:添加Baidu付款,Meituan付款,UnionPay付款等,您需要更改Topay方法的代码方法,请添加新的其他...如果判断,判断是否会导致越来越多的逻辑?

  显然,设计模型的六个原则在这里是非法的:开放和关闭的原则和单一职责。

  开放和关闭原则:打开和打开,并关闭。也就是说,有必要尽可能地更改新功能。

  单个职责原则:顾名思义,逻辑必须尽可能单一。不要太复杂且易于重复使用。

  那么,如何优化是否……判断?

  答案:使用 +。

  策略模式定义了一组算法,这些算法将它们一个一个一个封装,并允许它们彼此替换。该工厂模型用于创建包装和管理对象,这是创建模型。

  该代码的关键是PaystrategyFactory类。这是一个定义全球地图的战略工厂。在所有IPAY实现类中注册当前实例,然后通过地图从地图上获取PayStrateGyFactory类。

  如果添加了新的付款方式,您只需要拥有一个新类即可实现IPAY接口,定义INIT方法并重写付费方法。其他代码基本上可能不会移动。

  当然,有很多方法可以消除臭味和长时间的判断,例如:使用注释,动态缝合类别,模板方法,枚举等等。这里还有更多。有关更详细的内容,您可以阅读另一篇文章“消除... else是9个苗条”

  当看到这个标题时,一些朋友可能会感到有些惊讶。代码不应该避免死亡周期吗?为什么有死周期?

  众所周知,我们编写了一些死循环,例如,以下代码:

  这是一个(true)的圆形呼叫,以这种方式使用更多。

  当条件等于true时,循环将自动退出。

  如果条件非常复杂,一旦判断不正确或编写了更少的逻辑判断,则在某些情况下可能会出现死周期的问题。

  死周期是由开发人员的人造错误引起的,但是这种情况很容易测量。

  还有一个更深的死周期,这是由代码的严格写作较少引起的。如果使用正常数据,可能无法测量问题,但是一旦发生异常数据,则会立即出现死周期。

  实际上,还有另一种死周期:。

  如果要打印所有分类的分类,则可以使用此递归方法实现:

  在正常情况下,此代码没有问题。

  但是,如果某人滥用它,则分类的parentid会本身定向,这将具有无限的递归。结果,接口无法返回数据,并且最终将发生堆栈溢出。

  建议编写递归方法时,设置递归深度。例如,最大分类级别具有4个级别,并且可以将深度设置为4.然后在递归方法中做出判断。如果深度大于4,则将自动返回,以避免无限循环。

  通常,我们定义一些少量类型(例如:数量),而不是避免准确性丧失。

  使用Double时可能会有这样的场景:

  在正常情况下,预计金额2 -Amount1应等于0.01

  但是执行结果是:

  实际结果小于预期结果。

  双重类型的两个参数将转换为二进制,因为有效的double是1String requestUrl =“ http://susan.sc.cn?username=%S&adddress=%S&address=%S&roledId =;url = string.format(requestUrl,用户名,年龄,地址,性别,roledid); 1位将没有足够的存储十进制数字,在这种情况下将发生错误。

  常识告诉我们,可以避免使用损失的使用。

  但是,可以使用BigDecimal避免失去准确性吗?

  答案是负面的。

  为什么?

  此示例定义了两个BigDecimal类型参数,初始化构造函数,然后在减法后打印两个参数的值。

  结果:

  不是科学的,为什么您仍然失去准确性?

  中间有这样的描述:

  重点是,该构造函数的结果可能是不可预测的,并且在创建时可能发生0.1,但实际上是0.10000000000000000000000000000005555555555StringBuilder urlBuilder = new StringBuilder = new StringBuilder(“ http://susan.susan.sc.cn?”);urlbuilder.append(“” username =“).appnd(username).appnd(“”&age =“).appnd(apk).appnd(“&address =”).appnd(address).appnd(“&sex)=“).appnd(sex).appndid(“”&rooted =“).appnd(rootidid); 93StringBuilder urlBuilder = new StringBuilder(“ http://susan.sc.cn.sc.cn?cn?”);&age =“)。appnd(age).appnd(“”&address =“).appnd(address).appnd(“&sex =”).appnd(sex).appnd(“&routid =”).appndid(rootdid); requestUrl = =“ http://susan.sc.cn?username=%S&age=%S&address=%S&sex = %S&roledid = %S”; string url url = string.format(requestUrl,username,username,aghed)。

  可以看出,BigDecimal构造函数的初始化也可能会失去准确性。

  那么,您怎么会不会失去准确性呢?

  我们可以使用如何转换小数的双重数,以确保准确性不会丢失。

  实际上,有更好的方法:

  使用方法初始化BigDecimal类型参数也可以确保不会丢失精度。在新版本的Alibaba Development Handbook中,还建议使用此方法创建BigDecmal参数。

  它可能是程序员最常用的快捷键。

  没错,我们是大自然的搬运工。哈哈哈。

  在项目的早期阶段,我们可以使用此工作模型来提高某些工作效率,并且我们可以更少(实际上)编写很多代码。

  但是它带来的问题是:大量代码重复。例如:

  在TestService1,TestService2,TestService3中,有一个添加日志的Addlog方法。

  该功能一直很好地使用,直到有一天出现在线上:服务器磁盘已满。

  原因是打印的日志太多。我记得很多不必要的日志,例如:接口的所有返回值,大对象的特定打印等。

  绝对没有办法,您只能将Addlog方法更改为仅记录日志。

  结果,您需要搜索全文,修改了AddLog方法,并且更改了以下代码:

  以下是需要修改此代码的三个类别,但是如果实际工作中有三十或300个类别,它将使您非常痛苦。改变错误或泄漏后,隐藏的危险将被埋葬并陷入困境。

  为什么不提取此功能代码并将其放入工具类中?

  然后,只需在其他地方打电话即可。

  如果有一天要更改AddLog的逻辑,则只需要修改Logutil类的AddLog方法。您可以自信地修改,并且不再需要小心。

  我们编写的大多数代码都是维护的代码,而不是一个时间。因此,建议在编写代码的过程中,如果出现重复代码,请尝试将其提取到公共方法中。不要掩盖该项目的隐藏危险因为该项目在项目开始时令人耳目一新,并且维护成本可能很高。

  我们知道,在Java中,有很多在周期中写作的方法,例如:while,for,for foreach,for。

  结果:

  循环方法中的删除元素可能报告为异常。

  如果要在遍历集合时删除元素,则可以用于循环,例如:

  结果:

  当我们编写代码时,打印日志是必不可少的任务之一。

  因为日志可以帮助我们快速找到问题,并判断当时代码的真实实现逻辑。

  但是,当打印日志时,您需要注意,不要随时打印日志,例如:

  对于某些查询接口,在日志中打印了请求参数和接口返回值。

  乍一看没有问题。

  但是,如果ID中有很多输入值,例如1,000。该接口的频率很高,并且将立即打印大量日志,并且可以在填充之前已满。

  如果我真的想打印这些日志怎么办?

  使用判断,如果当前日志级别仅打印。生产环境的默认日志级别是,在某些紧急情况下,将某个接口或方法的日志级别更改为日志级别以调试,打印我们需要的日志和将其调整回。

  我们很方便地找到问题,并且不会产生很多垃圾记录。

  在比较两个参数是否相等时,我们通常使用数字或方法。

  我在第15章中说,当使用数比较两个值时,可能存在问题。建议比较使用方法。

  这

  在上面的代码中,如果用户对象或user.getName()方法的返回值是异常。

  那么,如何避免空气指针异常?

  这

  使用它进行比较时,请尝试编写正面,即等于方法的左侧。

  通过这种方式,即使用户返回的数据为null,equals方法也会直接返回false,而不是异常指针。

  Java中没有强制性规定的参数,方法,类或软件包。但是,如果我们不养成好习惯并随意命名,可能会有许多奇怪的代码。

  有时,当我们编写代码时,我们可以节省时间(您可以更少的字母)。参数名称越简单,越好。如果同事A编写的代码如下:

  一段时间后,同事A左派,同事B接管了代码。

  目前,他是积极进取的,是什么意思,b是什么意思,c ...然后他的心中有10,000匹草泥马。

  给参数一个有意义的名称,避免为您自己或他人避免使用坑非常重要。

  正确的:

  有意义的参数名称还不够,我们无法追求此信息。我们的参数名称最好,否则会发生这种情况:

  这些参数名称看起来有些怪异吗?

  您为什么在国际上定义英语单词(地球可以理解)英语单词?

  上面的两个参数名称基本上可以理解,从而降低了很多通信成本。

  因此,建议在定义参数名称,方法名称和类名称时,优先级使用世界上的国际英语单词,这更简单,更直观,可以降低通信成本。使用少的人,拼音或数字定义名称。

  实际上,参数名称的样式很多,例如::

  如果在某个类别中定义了各种参数名称,它看起来有点混乱吗?

  因此,建议成员变量,局部变量和方法参数使用供应商。这是:第一个字母小写和后续单词的第一个字母。例如:

  此外,为了区分,建议使用静态常数来使用supplier_count,即部分参数名称。例如:

  在Java8之前,通常通过类实施时间的格式。例如:

  如果您真的以这种方式写作,那没关系。

  恐怕有一天,您认为dateFormat是固定的代码,应该将其提取成恒定。

  因此,将代码更改为以下内容:

  DateFormat对象定义为静态常数,因此可以共享所有对象。

  如果只有一个线程可以调用时间方法,则不会出现问题。

  但是,Controlter类通常调用Serivce类的方法,并且Controller类的接口方法将被调用。换句话说,多个线程似乎调用了同一控制器类的相同方法,即多个线程线程将同时调用时间方法。

  调用类方法的方法:

  此方法将调用该方法:

  步骤1、2和3是非原子操作。

  但是,如果cal对象是局部变量,那么当解析方法调用建立方法时,坏处是不好的,则在类中传输的日历是父类的成员:

  这样,可能会出现多个线程,并且同时修改了相同的对象:dateFormat,其相同的成员变量为:日历值。

  这可能会出现,某个线程设置了时间,并通过其他线程进行了修改,因此时间是错误的。

  那么,如何解决这个问题?

  我们都知道,在提供后,可以使用它。

  线程池有很多好处。以下主要是关于这三个方面的。

  当然,JDK对我们来说更方便使用它,并且它是专门提供的:快速创建的类别。

  该课程包含很多:

  在高层场景中,如果您使用这些静态方法来创建线程池,将会出现一些问题。

  那么,让我们看一下什么问题?

  我们应该做什么?

  建议优先级,我们自定义线程池。

  特定代码如下:

  顺便说一句,如果它是一个低平行的场景,则不必用一堂课创建线程池,并且不能完全杀死。根据实际业务方案进行选择。

  在我们的日常工作中,我们经常需要转换为收藏。

  由于数组的长度是固定的,因此不容易扩展,并且列表的长度是可变的,并且其长度将根据元素数量动态扩展。

  JDK类中提供了一种可以转换为的方法。

  这

  在此示例中,数组数组用于直接用数组转换数组阵列。隔离方法。然后遍历for循环中的列表以打印出其中的元素。

  如果使用转换,仅使用它,则没有新的或修改的元素,也没有问题。

  这

  结果:

  将直接报告异常。

  为什么?

  答:使用方法转换后,它是类的内部类,而不是我们使用的。

  数组类中的ArrayList类未实现父类,并使用parent Abstractlist的默认实现来删除方法。

  让我们看看它是如何实现的:

  该类的方法是直接异常的,因此添加和删除方法的Araays类的Araylist类也异常。

  老实说,Java代码优化是一个相对较大的主题。它可以非常优化,我不能一一完成。我将介绍更常见的知识点和更全面的内容。您需要自己思考和探索它们。

  这篇文章已经写了很长时间,需要花费大量时间和思考。如果您阅读了一些文章,请记住给我一个赞美和鼓励。

  如果本文对您有帮助或灵感,请帮助扫描QR码以关注它。您的支持是我坚持写作的最大动力。

  寻求一个按钮和三个公司:喜欢,向前和观看。

  请注意公共帐户:[Su San Said Technology],在公共帐户中答复:面试,代码文物,开发手册,具有超级粉丝福利的时间管理,除了:Jiaqun,您还可以向前者进行交流和学习许多BAT制造商,向许多Bat Manufacturersence的前辈学习

  原始:https://juejin.cn/post/7stringbuilder urlbuilder = new StringBuilder(“ http://susan.sc.cn?”);urlbuilder.appnd(“用户名=”).appnd(用户名)。appnd(sex).appnd(“&dootid =”).appndid(rootdid);924003700719StringringRequestUrl =“ http://susan.sc.cn?username = %S&age=%S&address=%S&sex = %S&ss&roledid = %S”;字符串url = string.format(requesturl,用户名,aghed)。11String requestUrl =“ http://susan.sc.cn?username=%S&age=%S&address=%S&sex=%S&roledid =%s”;字符串url = string.format(requesturl,用户名,地址,ads ,, roledid);131