课堂任务
Java是由Sun公司于1995年推出的高级程序设计语言。2009年,甲骨文(Oracle)公司宣布收购Sun公司。
Java之父:詹姆斯·高斯林(James Gosling)
Java语言平台版本
- Java SE(Java Standard Edition)标准版
是为开发普通桌面和商务应用程序提供的解决方案,该技术体系是其他两者的基础,可以完成一些桌面应用程序的开发。 - Java ME(Java Micro Edition)小型版
是为开发移动设备和嵌入式设备(电器、机器人、机顶盒…)提供的解决方案。 - Java EE(Java Enterprise Edition)企业版
是为开发企业环境下的应用程序提供的一套解决方案,该技术体系中包含的技术如 Servlet、Jsp等,主要针对于Web应用程序开发。
JDK、JRE、JVM的关系,Java能跨平台的原因
- JVM(Java Virtual Machine)
Java 虚拟机,它只认识 xxx.class 这种类型的文件,它能够识别 class 文件中的字节码指令并调用对应操作系统上的API完成动作。此外,JVM 是 Java 能够跨平台的核心。 - JRE(Java Runtime Environment)
Java 运行时环境,为 Java 的运行提供了所需环境。它主要包含两个部分,JVM 的标准实现和 Java 的一些基本类库。它相对于 JVM 来说,多出来的是一部分的 Java 类库。如果你的电脑不是用来开发 Java 程序的,而仅仅是用来部署和运行 Java 程序的,那么只需要安装 JRE 即可。 - JDK(Java Development Kit)
Java 开发工具包,提供了 Java 的开发环境和运行环境。JDK 是整个 Java 开发的核心,它不仅包含了 JRE,同时还包含了编译 Java 源码的编译器 Javac,还包含了很多 Java 程序调试和分析的工具。
通过上面的信息,可以得出以下结论:
JDK>JRE>JVM
如果你需要运行 Java 程序,只需安装 JRE 就可以了,如果你需要编写 Java 程序,需要安装 JDK。
Java 能够跨平台运行的核心在于 JVM 。不是 Java 能够跨平台,而是它的 JVM 能够跨平台。
我们都知道,不同的操作系统上的 API 肯定是不同的,那么如果我们想要写一段代码调用系统的声音设备,就需要针对不同系统的 API 写出不同的代码来完成动作。那么这样的话,太麻烦了。
而 Java 引入了字节码的概念,JVM 只能认识字节码,并将它们解释到系统的 API 调用。针对不同的系统有不同的 JVM 实现,有 Linux 版本的 JVM 实现,也有 Windows 版本的 JVM 实现,但是同一段代码在编译后的字节码是一样的。继续沿用上面的例子,在 Java API 层面,我们调用系统声音设备的代码是唯一的,和系统无关,编译生成的字节码也是唯一的。但是同一段字节码,在不同的 JVM 实现上会映射到不同系统的 API 调用,从而实现代码的不加修改即可在不同平台运行(前提是已经安装好了与操作系统版本对应的 JVM )。
安装Java
Eclipse
Eclipse 是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。
安装Eclipse
参考2020最新eclipse安装教程,配有每一步的安装过程和细节!
创建Java项目
创建包
创建HelloWorld类
注意类名要符合驼峰式命名法。
说明
/*
* 用来定义一个包,package加粗变红的效果,叫做关键字,专门用来定义包
* com.iweb.hello 包名 全小写,域名+项目名/模块名
* ;号 结束语,相当于。号
*/
package com.iweb.hello;
/*
* 定义一个类
* public 关键字 修饰词,用来修饰访问权限,表示公开的,公共的
* class 关键字 专门用来定义类,
* HelloWorld 类名,满足驼峰式命名规则
* {java代码}
*/
public class HelloWorld {
/*
* 方法的声明,main主方法/主函数
* public 关键字 修饰词,用来修饰访问权限,表示公开的,公共的
* static 关键字 修饰词,用来修饰main方法是静态的
* void 关键字 表示main方法没有返回值
* ()小括号,方法的标志
* String[] args 方法参数
* {java代码|方法体}
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
/*
* 用来向控制台输出指定的数据
* 需要输出的数据放在()小括号里
* 向控制台输出"HelloWorld"这个字符串
*/
System.out.println("HelloWorld");
}
}
运行
运行过程
-
编译
通过javac命令将 java 的源文件也就是 .java 文件编译成 .class 文件。 -
执行
先启动 java 虚拟机,不同的操作系统有不同的 jvm ,因此 java 跨平台。再通过 jvm 加载 HelloWorld.class 字节码文件。并加载 main 方法执行程序。
Java常识
标识符
可以简单的理解为一个名字。在Java中,我们需要标识代码的很多元素,包括类名、方法、字段、变量、包名等。我们选择的名称就称为标识符,并且遵循以下规则:
- 标识符可以由字母、数字、下划线(_)、美元符($)组成,但不能包含 @、%、空格等其它特殊字符。
- 不能以数字开头。
- 标识符是严格区分大小写的。
- 标识符的命名最好能反映出其作用,做到见名知意。
关键字
Java 语言目前定义了 51 个关键字,这些关键字不能作为变量名、类名和方法名来使用。以下对这些关键字进行了分类。
- 数据类型:
boolean、int、long、short、byte、float、double、char、class、interface。 - 流程控制:
if、else、do、while、for、switch、case、default、break、continue、return、try、catch、finally。 - 修饰符:
public、protected、private、final、void、static、strict、abstract、transient、synchronized、volatile、native。 - 动作:
package、import、throw、throws、extends、implements、this、supper、instanceof、new。 - 保留字:
true、false、null、goto、const。
注释
Java代码的解释说明。不影响程序的运行,用于辅助阅读代码。
// 单行注释,注释一行
/*
* 多行注释
* 注释多行
*/
/**
* 文档注释,可以生产doc文档
*/
变量
在JAVA中,有的数据值是不固定的,会改变,我们还需要记录这些值,我们可以把这些值理解为变量。
我们通过三个部分来描述变量:变量类型,变量名以及变量值。这三部分都是可以改变的,根据需要来确定即可。
int age=18; //声明int类型的变量并赋值
String tel; //声明String类型的变量
注意:
- 变量名必须是一个有效的标识符。
- 变量名不可以使用java关键字。
- 同一作用域下,变量名不能重复。
常量
在程序运行过程中一致不会改变的量称为常量。
final String MAN="男";
final String FEMALE="女";
数据类型
基本数据类型(8种)
位bit,字节byte,1byte=8bit
基本类型 | 类型名称 | 长度 | 默认值 | 取值范围 | 对应的封装类 |
---|---|---|---|---|---|
整数型 | byte | 8位 | (byte)0 | -2⁷~2⁷-1 | Byte |
short | 16位 | (short)0 | -2¹⁵~2¹⁵-1 | Short | |
int | 32位 | 0 | -2³¹~2³¹-1 | Integer | |
long | 64位 | 0L | -2⁶³~2⁶³-1 | Long | |
浮点型 | float | 32位 | 0.0F | 单精度,小数部分精度不高 | Float |
double | 64位 | 0.0D | 双精度,小数部分精度更高 | Double | |
字符型 | char | 16位 | u0000(null) | 0~65535 | Character |
布尔型 | boolean | 8位 | false | 真true,假false | Boolean |
Scanner
- 输入个人信息,并打印结果
package com.iweb.hello;
// 导入Scanner工具类
import java.util.Scanner;
/**
* 练习2 输入个人信息,并打印结果
* 使用Scanner的步骤
* 1.导入Scanner工具类
* import java.util.Scanner;
* 2.创建Scanner工具类对象
* Scanner scan = new Scanner(System.in);
* 3.调用Scanner提供的方法接收数据
* String name = scan.next();
*/
public class HelloWorld {
public static void main(String[] args) {
// 创建一个Scanner对象,
Scanner sc = new Scanner(System.in);
System.out.println("请输入姓名:");
//接收姓名数据,并保存到name变量中
String name = sc.next();
System.out.println("请输入年龄:");
//接收年龄数据并保存到age变量中
int age = sc.nextInt();
System.out.println("姓名:"+name);
System.out.println("年龄:"+age);
}
}
- 输入圆的半径,求圆的周长和面积
public class HelloWorld {
public static void main(String[] args) {
// 定义圆半径
double r;
// 接收圆半径
System.out.println("请输入圆半径:");
Scanner sc = new Scanner(System.in);
r = sc.nextDouble();
// 计算圆面积
double area = 3.14 * r * r;
System.out.println("圆的面积是:" + area);
// 计算圆周长
double circ = 2 * 3.14 * r;
System.out.println("圆的周长是:" + circ);
}
}
- 交换两个变量的值并输出它们
public class HelloWorld {
public static void main(String[] args) {
int a = 10;
int b = 20;
int temp;
temp = a;
a = b;
b = temp;
System.out.println("a=" + a);
System.out.println("b=" + b);
}
}
引用类型
引用类型是一个对象类型。它的值是指向内存空间的引用,就是地址,所指向的内存中保存着变量所表示的一个值或一组值。如:类,接口,数组等等。这些会在后续再讲。
字面类型
写着是什么值,实际就是什么值。
- 整数型字面值是int类型
byte b=127; //对,但右侧是int类型的数据
- byte、short、char三种比int小的整数可以用范围内的值直接赋值
byte b=128; //错,右侧已经超过byte类型的范围
- 浮点型的字面值是double类型
double a=3.14; //对
float a=3.14; //错,右侧是double类型,float是四字节,double是八字节,存不下
- 字面值的后缀LFD(lfd)
L –long 如:long a = 99999999999; //错,超出范围,解决方案加L
F –float 如:float a = 3.14; //错,右面是double类型,解决方案加F
D –double 如:double a=3D;
类型转换
小转大(隐式转换)
小类型转大类型通常是自动转换(隐式转换)。
byte a = 120;
int b = a; // 隐式转换
大转小(显示转换)
需要强制转换。注意:小数转成整数,小数部分会直接舍弃。
double a = 2.34;
int b = (int) a;
System.out.println(b); // 输出结果为2
运算规则
- 计算结果的数据类型,与最大类型一致
3/2 结果为1,而不是1.5,结果是int型
3D/2 结果为1.5,相当于double/int,结果是double型
- byte、short、char三种比int小的整数,运算时会自动转成int
byte a=3;
byte b=4;
byte c=a+b; // 报错,运行时,byte会先自动转成int再运算,int+int还是int
- 整数运算
整数运算,类似于一个中标,转到最大时,再转会回到最小。
int a = Integer.MAX_VALUE; // 获取整数的最大值
int b = Integer.MIN_VALUE; // 获取整数的最小值
System.out.println(" a="+a); // a=2147483647
System.out.println(" b="+b); // b=-2147483648
System.out.println("a+1="+(a+1)); // a+1=-2147483648
- 浮点数运算不精确
JAVA提供了解决方案,后面会讲到。
System.out.println(1-0.8); // 0.19999999999999996
System.out.println(4.35*100); // 434.99999999999994
- 浮点数的特殊值
System.out.println(3.14/0); // Infinity(无穷大)
System.out.println(0/0.0); // NaN(not a number)
运算符
补充
- 三元运算符
?
运算符是三元运算符。Java三元运算符基本上是简单的if语句的简写形式。
expression1 ? expression2 : expression3
expression1 可以是计算为 boolean 值的任何表达式。如果 expression1 是 true ,那么将返回 expression2 。否则,将返回 expression3 。
- 使用三元运算符求绝对值
public static void main(String[] args) {
int num, res;
num = 10;
res = num < 0 ? -num : num;
System.out.print("Absolute value of ");
System.out.println(num + " is " + res);
num = -10;
res = num < 0 ? -num : num;
System.out.print("Absolute value of ");
System.out.println(num + " is " + res);
}
条件语句
Java 条件语句 – if…else | 菜鸟教程
Java switch case 语句 | 菜鸟教程
- 输入年份,判断是平年还是闰年
/**
* 输入年号,判断是否是闰年。两个条件:
* 1、能被4整除,并且不能被100整除
* 2、或者能被400整除
*/
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String res;
System.out.println("请输入年份:");
int year = scan.nextInt();
if((year%4==0 && year%100!=0) || year%400==0 ) {
res = "闰年";
}else {
res = "平年";
}
System.out.println(year+"年是"+res);
}
- 输入分数,根据分数的高低给出相应的评价
/**
* 90分以上 优秀
* 80~89 良好
* 70~79 中等
* 60~69 及格
* 60分以下 不及格
*/
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
double score = scan.nextDouble();
if (score >= 100 || score <= 0) {
System.out.println("请输入0~100以内的值");
}
if (score > 90 && score <= 100) {
System.out.println("优秀");
} else if (score >= 80 && score <= 90) {
System.out.println("良好");
} else if (score >= 70 && score <= 79) {
System.out.println("中等");
} else if (score >= 60 && score <= 69) {
System.out.println("及格");
}else if (score < 60) {
System.out.println("不及格");
}
}
- 键盘输入月份(1~12),打印该月份的天数(不考虑闰年)
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("请输入月份:");
int month = scan.nextInt();
int day;
switch (month) {
case 1:
day=31;
break;
case 2:
day=28;
break;
case 3:
day=31;
break;
case 4:
day=30;
break;
case 5:
day=31;
break;
case 6:
day=30;
break;
case 7:
case 8:
day=31;
break;
case 9:
day=30;
break;
case 10:
day=31;
break;
case 11:
day=30;
break;
case 12:
day=31;
break;
default:
day=-1;
break;
}
if (day==-1) {
System.out.println("月份非法");
}else {
System.out.println(month+"月有"+day+"天");
}
}
循环结构
Java 循环结构 – for, while 及 do…while | 菜鸟教程
- 用for循环打印出8,88,888
public static void main(String[] args) {
for (int i = 0, num = 8; i < 3; i++) {
System.out.println(num);
num = num * 10 + 8;
}
}
- 猜数字(1~100)
public static void main(String[] args) {
System.out.println("猜数字(1~100)");
// 系统产生随机数,从0开始,要从1开始就加1
int rand = new Random().nextInt(100)+1;
System.out.println("生成的数字:"+rand);
Scanner scan = new Scanner(System.in);
while(true){
System.out.println("请猜数字:");
// 接收用户输入的值
int num = scan.nextInt();
// 判断
if(num>rand){
System.out.println("猜大了");
}else if(num<rand){
System.out.println("差小了");
}else{
System.out.println("猜对了");
break;
}
}
}
补充
三种循环都可以互相转换。往往在使用的时候,根据情形的不同来选择用哪一种循环。
- 使用for循环
循环次数已知。 - 使用while循环
循坏次数未知。 - do while
不管循环条件是否成立,先执行一次循环体的循环。
课后任务
-
【解答】说明&和&&的区别
&&:逻辑与,判断左边表达式为false时,就不会继续判断右侧的表达式。(会短路)
& :效果同&&,不管表达式结果为false还是true,都是会判断两边的表达式的结果。(不会短路) -
【编程】求三个数中的最大值,实现要求:控制台录入3个整数数据,并求出这3个数的最大值
public class Run {
public static void main(String[] args) {
int[] num = new int[3];
Scanner sc = new Scanner(System.in);
for (int i = 0; i < num.length; i++) {
num[i]=sc.nextInt();
}
int max = num[0];
for (int j : num) {
if (j > max) {
max = j;
}
}
System.out.println("max="+max);
}
}
- 【编程】商品打折程序,实现要求:接收用户输入的原价。满1000打9折。满2000打8折。满5000打5折
public class Run {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
double price = sc.nextInt();
if (price > 5000) {
price *= 0.5;
} else if (price > 2000) {
price *= 0.8;
} else if (price > 1000) {
price *= 0.9;
}
System.out.println("price=" + price);
}
}
- 【编程】打印正直角三角型,反直角三角形
public class Run {
public static void main(String[] args) {
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= i; j++) {
System.out.print("*");
}
System.out.println();
}
System.out.println();
for (int i = 5; i > 0; i--) {
for (int j = 0; j < 5 - i; j++) {
System.out.print(" ");
}
for (int j = i; j > 0; j--) {
System.out.print("*");
}
System.out.println();
}
}
}
5.【编程】打印九九乘法表
public class Run {
public static void main(String[] args) {
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(i+"×"+j+"="+i*j+" ");
}
System.out.println();
}
}
}
- 【编程】求n范围内的水仙花数,以及水仙花数的个数。
实现要求:在控制台录入一个数字,求这个数字范围内的水仙花数,术语解释:水仙花数是指一个3位数,它的每个位上的数字的3次幂之和等于它本身(例如:1^3 + 5^3+ 3^3 = 153)
public class Run {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入数字(100~999):");
int num = sc.nextInt();
if (num < 100 || num > 999) {
System.out.println("无结果");
} else {
int a, b, c, counts = 0;
int[] res = new int[900];
for (int i = 100; i <= num; i++) {
a = i / 100;
b = i % 100 / 10;
c = i % 10;
if (a * a * a + b * b * b + c * c * c == i) {
res[counts++] = i;
}
}
System.out.println("100~" + num + "范围内的水仙花数有" + counts + "个:");
for (int i = 0; i < counts; i++) {
System.out.print(res[i]+" ");
}
}
}
}
- 【编程】求100范围内的所有质数,术语解释:质数又称素数,有无限个。一个大于1的自然数,除了1和它本身外,不能被其他自然数整除
public class Run {
public static void main(String[] args) {
// res存结果,counts记质数个数,flag记录该数是否为质数
int[] res = new int[100];
int counts = 0;
boolean flag;
for (int i = 2; i <= 100; i++) {
flag = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
flag = false;
break;
}
}
if (flag) {
res[counts++] = i;
}
}
System.out.println("100以内的质数有" + counts + "个:");
for (int i = 0; i < counts; i++) {
System.out.print(res[i] + " ");
}
}
}
隐式转换的细节问题
public static void main(String[] args) {
int num = 9;
System.out.println(num>= 9 ? 8 : 10.0);
// 返回值是double型的8.0,而不是int型的8
// 因为三元运算符中有int和double,计算时会统一隐式转换成double
}