ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Java学习第二天:基础语法避坑指南与排序实战

Java学习第二天:基础语法避坑指南与排序实战 学Java的第二天刚好卡在“觉得有点意思”和“开始想放弃”的中间地带。第一天装完环境、跑通Hello World之后大多数人会陷入一种错觉Java好像也不难。但第二天开始碰数据类型、变量、运算符、流程控制这些Java基础语法时才发现处处是坑——命名规范记不住、整数和浮点数算不准、环境变量搞出多个JDK版本互相打架、写个排序都能越界报错。这篇文章就记录一下我在Java学习第二天实际走过的路环境配置的细节、数据类型与标识符的规则、手写冒泡排序和sort函数用法的对比、面向对象编程的第一个概念铺垫以及这一天最常遇见的几个问题和排查思路。内容面向刚装好JDK、准备正式进入Java语法学习的初学者也适合那些“学过两天又想重头再来”的朋友当作一份避坑清单。1. 第二天的学习定位今天不是学新东西是建立代码直觉很多人在Java学习第二天最容易犯的错误就是急着往后赶进度。看到别人聊Spring Boot、MyBatis Plus、微服务自己也想去碰结果连public static void main都写不利索。第二天真正该做的事情只有三件把第一天遗留的环境问题彻底清掉、把Java基础语法中的核心类型和结构跑熟、写出第一段带有业务逻辑的完整程序。1.1 先检查第一天是不是真的“装好了”装好JDK、能运行Hello World不代表环境就真的没问题。第二天一开始我建议先做一次完整的“环境体检”在命令行里依次执行java -version、javac -version、echo %JAVA_HOME%Windows或echo $JAVA_HOMELinux/macOS确认编译器和解释器都能正常工作。很多教程里只提到java -version但漏掉javac结果后面一编译就报“找不到javac”。这一步不是走形式。你后面要写任何超过一行的Java代码都绕不开编译环节。如果javac版本和你java版本对不上大概率是环境变量里混入了多个版本的JDK路径。这个问题第二天不解决后面学习到面向对象编程、写多类文件时会被反复折磨。1.2 第二天的核心学习清单掌握语法骨架第二天的学习内容我建议框定在这些范围内八大基本数据类型的定义、取值范围、默认值变量的声明、赋值、作用域标识符命名规则和驼峰命名习惯运算符、表达式与常见陷阱尤其是整数除法、取余、自增自减流程控制if/else、switch、for、while数组的声明、初始化、遍历方法函数的定义与调用这七个点看起来多但它们是同一个知识块——都是“数据和基本操作”。把这些内容串起来你就会发现一个规律几乎所有Java程序本质上都是“声明数据 流程控制 调用方法”的组合。第二天把这些骨架打牢后面学面向对象编程时才有地方挂靠新概念。2. 环境配置的深度解构JAVA_HOME、PATH 和多个JDK的问题2.1 环境变量背后的三个角色Java环境变量大概是初学者第一个“背了又忘、忘了又背”的知识点。其实理解起来很简单JAVA_HOME是告诉系统JDK装在哪PATH是告诉系统去哪个目录找命令CLASSPATH是告诉JVM去哪里加载类。现在大多数时候不需要手动配CLASSPATH但JAVA_HOME和PATH必须搞明白。以Windows为例配置JAVA_HOME的路径时要注意两点第一不要带多余的斜杠和空格比如C:\Program Files\Java\jdk-17\末尾的\会导致后续拼接路径时出现双斜杠第二PATH里引用的%JAVA_HOME%\bin必须放在常用命令路径之前否则系统可能先找到别的Java版本。2.2 多个JDK共存不要卸载老版本要学会切换很多人在学习过程中会装不止一个JDK公司项目要求Java 8自己学习想用Java 17这就产生了“多个JDK共存”的需求。我在第二天踩过一个坑把两个JDK同时写进PATH结果java -version显示的版本和javac -version不一致编译半天全是版本错误。正确做法是只把一个JDK的bin目录加入PATH其他JDK保留安装目录即可。需要切换时修改JAVA_HOME指向目标版本然后新开一个命令行窗口旧窗口的环境变量缓存不会刷新。Windows下也可以用where java看系统实际找到的是哪个路径。Linux/macOS用户则可以用update-alternatives --config java来切换系统默认版本比改脚本更稳妥。2.3 java启动失败的常见表现“java启动失败怎么解决”在搜索热度里一直很高第二天最容易撞见的是这两种一是Error: Could not find or load main class二是UnsupportedClassVersionError。前者多半是你运行java Hello时命令行类名写错或者当前目录不对后者是编译版本和运行版本不一致比如用JDK 17编译的class文件丢到JDK 8的环境跑。遇到这类报错先别慌按这个顺序排查先javac -version和java -version对比版本再确认当前路径下class文件存在最后检查是不是类名大小写和文件名不一致。提示Java类名严格区分大小写文件名和public类名必须完全一致。这个规则第二天就记住能省下后面很多编译报错的时间。3. 数据类型与变量基础中的基础坑里的坑3.1 八大基本数据类型一张表看懂Java的数据类型是第二天必须完全背下来的内容面试题也爱从这里面出。八个基本类型可以分成四组类型关键字占用空间取值范围说明默认值字节型byte1字节-128 ~ 1270短整型short2字节-32768 ~ 327670整型int4字节-2^31 ~ 2^31-10长整型long8字节-2^63 ~ 2^63-10L单精度浮点float4字节约±3.4E38有效位6~7位0.0f双精度浮点double8字节约±1.7E308有效位15位0.0d布尔型boolean理论上1位true / falsefalse字符型char2字节0 ~ 65535Unicode字符\u0000这里有个特别容易忽略的点long类型赋值时结尾要加L或llong big 1234567890123L;不加L会直接编译报错因为整数默认按int处理超出范围就无法自动转换。float类型赋值结尾要加F或f同理。这个细节第一天不碰第二天写代码时立刻就会遇到。3.2 为什么说浮点数不能直接比较数据类型里最反直觉的是浮点数。我第二天写过一个测试0.1 0.2 0.3结果返回false。这不是Java的Bug而是IEEE 754标准下二进制无法精确表示0.1这类十进制小数的天然限制。类似生活化的理解你用十进制可以精确写出1/3吗只能写成0.3333……计算机用二进制表示某些十进制小数也是一样。这个知识点看起来很理论但直接影响后续编程习惯。涉及金额计算时必须用BigDecimal而不是double这几乎是Java面试八股文里的必考题。第二天能意识到“浮点数不等于精确数”这一点后面学到BigDecimal时会理解得特别快。3.3 变量作用域大括号决定生死变量的作用域规则是第三天开始写方法、写循环体时最常见的Bug来源之一。规则很简单变量从声明处开始到所在的那一层大括号结束为止都有效。但初学者常犯两种错误——在for循环内部声明的变量循环外使用在if分支里声明的变量分支外用。编译器直接报找不到符号但是很多人第一反应不是查作用域而是怀疑环境坏了。我当时的排查方法比较笨也有效把变量声明往上层提一级再一层层往下收缩通过编译器的报错位置反推作用域边界。这个方法放到现在依然推荐它能帮你快速建立“变量的可视范围”直觉。4. 标识符命名规范从第二天起就要有“面向面试”的自觉4.1 硬性规则不能越界的红线Java标识符的硬性规则并不多但每条都是编译器的红线由字母、数字、下划线_、美元符号$组成不能以数字开头不能使用Java关键字和保留字比如class、int、public、if都不能作为标识符严格区分大小写Name和name是完全不同的标识符没有长度限制但实际写代码时建议控制在20个字符以内上面四条里第二条和第三条是面试中最高频的考点。我见过有人试图用int class 1当变量名编译报错后还不明白为什么。这个规则的底层逻辑其实很简单关键字是语言自己的指令你在程序里定义一个叫class的变量编译器就分不清它是“声明类”的关键字还是你的变量了。4.2 驼峰命名法区分大驼峰和小驼峰硬性规则之外行业里约定俗成的是驼峰命名法。大驼峰用于类名每个单词首字母大写比如StudentInfo、OrderService小驼峰用于变量名和方法名第一个单词首字母小写后续单词首字母大写比如studentName、getTotalPrice()。常量则用全大写加下划线比如MAX_VALUE、DEFAULT_TIMEOUT。为什么要在第二天就强调命名规范因为命名习惯一旦形成后面很难改。我自己在刚开始写代码那阵子习惯用a、b、temp这种简写变量名到后面自己回头看代码都看不懂。更现实的问题是面试手写代码时命名是否规范会被面试官当作“是否接受过正规训练”的信号。所以第二天开始尽量用有意义的单词组合别怕打字多。4.3 包名与类名的配合包名一般用公司域名的倒写比如com.example.learningpackage声明必须放在文件第一行注释除外。这个知识点第二天先有个印象即可真正理解要等到学面向对象编程和项目工程化之后。但与标识符直接相关的一点可以立即实践一个Java文件中只能有一个public类且类名必须与文件名相同。这个规则第二天不记第三天写两个类时就大概率踩坑。5. 第一个有业务含义的代码冒泡排序与Arrays.sort5.1 为什么第二天要写排序排序几乎是所有Java学习路线里第一个“理论上听懂、动手必错”的算法题目。选择它作为第二天的实战项目有几个原因它同时用到数组、循环、比较运算符、临时变量交换值这些前一天或当天刚学的语法点它拥有非常直观的“可视化”过程方便对照代码检查逻辑它还会引出“自己写算法 vs 调用现成API”的工程思维对比后面学习常用库函数时会有强烈共鸣。5.2 冒泡排序的思路让大的数一路“冒”到末尾冒泡排序的核心思想是从头开始依次比较相邻两个元素把较大的往后移动。一趟下来最大的元素就像气泡一样浮到了数组最后面。然后对剩下的部分重复这个过程。用大白话说就是“每轮冒泡确定一个最大值的位置”。最坏情况下要做n-1轮每轮比较n-1-i次i为已经完成的轮数。不急着解释时间复杂度O(n^2)的数学推导第二天只要理解“两层循环外层控制轮数内存控制比较次数”就够了。5.3 手写冒泡排序并逐行解释下面是我第二天实际写出来并跑通的版本注释写得很啰嗦但适合初学者逐行对照public class BubbleSort { public static void main(String[] args) { int[] arr {5, 1, 4, 2, 8}; // 外层循环控制排序轮数总共需要 n-1 轮 for (int i 0; i arr.length - 1; i) { // 内层循环进行相邻元素比较 // 每轮结束后最后 i 个元素已经排好无需再比较 for (int j 0; j arr.length - 1 - i; j) { if (arr[j] arr[j 1]) { // 交换相邻两个元素的位置 int temp arr[j]; arr[j] arr[j 1]; arr[j 1] temp; } } } // 遍历输出结果 for (int num : arr) { System.out.print(num ); } } }这段代码里有个很经典的细节交换两个变量的值必须借助临时变量temp。很多新手第一反应写arr[j] arr[j1]; arr[j1] arr[j];跑完发现数组全变成了同一个值。原因在于第二条语句执行时arr[j]已经被覆盖了。这个错误不重要但它说明一个道理写代码时要时刻关注“变量的当前值”和“执行顺序”。如果觉得每次都要手写交换太啰嗦后面学到异或运算时可以用arr[j] ^ arr[j1]; arr[j1] ^ arr[j]; arr[j] ^ arr[j1];做无临时变量交换但第二天不建议这么写可读性太差面试时反而容易被问住。5.4 直接调用Arrays.sort要知道“拿来主义”的边界手写完冒泡排序后马上应该知道Java标准库提供了现成的排序方法Arrays.sort()。用法非常简单import java.util.Arrays; public class SortDemo { public static void main(String[] args) { int[] arr {5, 1, 4, 2, 8}; Arrays.sort(arr); System.out.println(Arrays.toString(arr)); } }这里有个常见的“半懂不懂”状态Arrays.sort能排序为什么还要学冒泡排序答案有两层。第一层是基础能力问题面试和考试比如蓝桥杯经常要求手写排序逻辑你必须理解底层过程才能应对“改一下排序规则”“统计交换次数”这类变形题。第二层是工程素养问题Arrays.sort在JDK里的实现会根据数据量和数据特点自动选择快速排序、插入排序或归并排序它的排序对象还可以支持自定义比较器。直接调用API是“用工具”手写算法是“造工具”两条腿都要走。sort函数的进阶用法第二天先知道原理即可Arrays.sort(T[] a, Comparator? super T c)可以对对象数组按自定义规则排序比如按字符串长度排、按对象的某个属性排。这一步在学到面向对象编程后会自然理解不用急着背。6. 面向对象编程第二天只打地基不盖楼6.1 用生活化类比理解类和对象第二天如果直接学面向对象三大特性封装、继承、多态大概率是懵的。我建议先把“类”和“对象”这两个词盘明白。用做蛋糕类比类是模具对象是用模具做出来的蛋糕。模具决定了蛋糕有什么属性大小、形状和能力能不能裱花但模具本身不是蛋糕同样类定义了数据和方法真正占用内存的是根据类创建出来的对象。实例化对象的语法很简单类名 对象名 new 类名();这行代码要拆三部分看类名是声明引用类型new是真正的创建对象new 类名()是调用构造方法完成初始化。第二天可以不深入构造方法但要先记住一个现象只要new了就有一块新的对象在堆内存里创建出来。6.2 一个最小可运行的类面向对象编程的入门代码我第二天写的是一行模拟学生信息的类。不涉及继承和多态只涉及属性、方法、对象调用public class Student { // 属性描述对象的状态 String name; int age; // 方法描述对象能做什么 void introduce() { System.out.println(我叫 name 今年 age 岁); } public static void main(String[] args) { // 创建对象 Student s new Student(); // 给属性赋值 s.name 小明; s.age 18; // 调用方法 s.introduce(); } }这一段代码把第二天学的数据类型、变量、方法调用全部串起来了。运行结果会输出“我叫小明今年18岁”。建议当天把这个代码改造几遍多加一个hobby属性再写一个eat()方法感受一下“类描述一类事物”的感觉。6.3 方法的重载第二次遇到同一个名字方法重载Overload是面向对象编程之前一个相对独立且容易理解的概念同一个类里可以有多个同名方法只要参数列表不同。比如public class Calculator { int add(int a, int b) { return a b; } int add(int a, int b, int c) { return a b c; } }第二天理解到这个程度就差不多了。“名字相同、参数列表不同”这句话后面在构造方法、Spring框架里的Overload相关用法中会反复出现。现在打个小地基将来不慌。7. 第二天最容易踩的坑问题排查与避坑清单7.1 Error: Could not find or load main class这个报错排在我第二天遇到的“最气人Bug”第一名。报错信息很清楚但原因往往有好几种。我当时的实际场景是类名是HelloJava文件名也是HelloJava.java编译通过但运行时用了java hellojava小写开头——立马报错。第二种常见场景class文件生成在src目录下但你不在src目录里运行java命令类文件自然找不到。排查步骤按顺序来确认当前目录下存在对应的.class文件确认类名与文件名完全一致大小写也一致确认运行时类名不包含.class后缀java Hello.class是错误写法如果用了package声明运行时必须在包结构的根目录执行并写完整类名Day 2如果没用IDE集成开发环境这些问题会特别常见。所以我个人建议第二天开始直接用IntelliJ IDEA这类IDE练习让IDE帮你处理编译和类路径问题把精力放在语法和逻辑上。7.2 OutOfMemoryError: Java heap space 合理应对虽然OutOfMemoryError在第二天很少遇到但我当时因为用IDEA频繁编译运行一个写错循环条件的程序死循环不断创建对象确实撞到过一次这个报错。在IDEA里修改运行内存的方式是Help - Edit Custom VM Options调整-Xmx参数比如-Xmx2048m。但更重要的不是调大内存而是检查代码逻辑——如果程序本身无限循环再大的堆也会被填满。关于堆大小这个名词第二天先建立一个粗略概念堆是Java虚拟机管理的一块内存区域用来存放对象实例。JVM启动时通过-Xms初始堆大小和-Xmx最大堆大小控制。很多生产环境问题都跟这两个参数有关这类内容属于Java工程师面试常问的JVM知识块第二天不必深究但见到名字混个脸熟。7.3 中文乱码问题Windows命令行下运行包含中文的Java代码经常输出乱码。原因几乎都是编码不一致源文件是UTF-8而命令行默认用GBK读取字节。解决办法有两种一是编译时指定编码javac -encoding UTF-8 Hello.java二是类文件编译已完成运行时加-Dfile.encodingUTF-8。如果用的是IDE在设置里统一把File Encoding切到UTF-8就不会有这个问题。7.4 常见问题速查表现象可能原因处理建议javac不是内部或外部命令PATH未包含JDK的bin目录检查JAVA_HOME和PATH配置版本显示和预期不符多个JDK共存PATH顺序问题用where java查路径调整PATH顺序中文乱码编译或运行编码不一致统一源文件和命令行的编码为UTF-8找不到或无法加载主类类名写错、目录错误、漏package前缀按类名、路径、包名顺序排查数组下标越界循环边界设置错误检查arr.length以及下标从0开始程序运行后无输出main方法漏写或有死循环确认方法签名public static void main(String[] args)8. 第二天结束前你应该能做到什么8.1 把“学习路线”放远一点看Java学习路线本身是一个很有争议的话题因为不同起点、不同目标的人需要不同的路径。但大致框架是有共识的基础语法 - 面向对象 - 常用API集合、IO、多线程- 数据库与JDBC - Web开发Servlet/Spring Boot- 框架与工具MyBatis、Maven、Git。第二天只走到第一步的前半段不用焦虑。热搜里那些“Java工程师面试题”、“MyBatis Plus根据实体类生成建表SQL”之类的内容对第二天的你很遥远看了只会徒增焦虑。明确一个认知任何一门技术“看起来会了”和“真的会了”之间存在巨大鸿沟而第二天正是跨越这个鸿沟的起点。不要用“收藏了就等于学了”来安慰自己第二天结束前的唯一标准是你能不翻笔记独立写完一个包含数组、循环、条件判断和方法的完整小程序。8.2 一个可用来检验自己的小练习我第二天结束前用来验收自己的一道小题目分享出来供参考定义int[] scores {78, 93, 85, 66, 90};写代码完成三件事计算平均分、找出最高分、输出所有不及格低于60的分数。这道题覆盖了数组遍历、条件判断、变量累积、两两比较算是第二天语法的综合测试。如果能不查资料独立写出来说明第二天的语法基础基本牢固可以进入面向对象的学习。8.3 关于学习方法的个人心得第二天最容易陷入的“假努力”状态是视频看了两个小时笔记抄了几大页但自己一行代码没敲。这和我当年学习的情况一模一样。后来我给自己定了一个规矩——看完任何一个知识点必须立刻在代码里用一遍哪怕是最小的例子。比如学完变量就声明一个布尔变量判断5 3然后打印学完循环就写一个打印九九乘法表的程序。这种“输入后马上输出”的方式让第三天的学习效率明显提高了一个档次。另外准备一个自己的“报错收集本”。我当年把所有遇到过的编译错误、运行异常都复制到一个文档里配上出错时间和简单解决思路。这个习惯保持到工作后意外的收获是面试时聊“你最常遇到的问题”时我总能拿出真实经历并不复述教程。第二天如果只记住一件事我希望把“多敲代码”这句话认真执行起来。Java是一门实践性极强的语言所有看不懂的概念几乎都是因为代码量不够。今天的语法骨架上后续面向对象编程、集合框架、异常处理这些内容才有地方生根。把冒泡排序这种经典的练习用不同写法多敲几遍把命名规范和数据类型当成常识刻进脑子里往后的路会越走越顺畅。
返回列表