Java的概念
1. 什么是Java
Java是一门面向对象
语言,Java的语法与C与C++的语法很接近。
Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点 。
Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等。
2. Java的特点
- 分布式:Java支持intent应用开发,有一个网络应用编程接口(Java net),Java的RMI机制是开发分布式应用的重要手段。
- 健壮性:Java的强类型机制、异常处理、垃圾回收机制保证了Java的健壮性,(指针的丢弃是明智之举)。
- 安全性:Java有一个安全防范机制(classloader),防范恶意代码的攻击;以及分配不同的名字空间防止替代本地的类、字节码检查。
- 平台独立:Java程序在Java平台编译。
- 可移植:Java程序编译后,可在实现Java平台(JVM)的任何系统的解释器中运行。
- 多线程:Java是支持多线程的。
3. Java程序运行和环境搭建
运行Java程序需要Java环境(JVM),需要安装JDK
JDK包含内容:
- JVM虚拟机:JAVA运行程序的地方。
- 核心类库:JAVA已经写好的东西,我们可以直接使用。
- 开发工具:javac、java、jdb、jhat…
简单的说,JDK就是编写和运行java程序的工具包。
3.1 JDK和JRE的区别
- jdk:Java开发工具包,提供了Java的开发环境和运行环境。
- jre:Java运行环境。
JDK包含了JRE,同时包含了编译Java源码的编译器javac和Java程序的调试和分析的工具。
换句话说,如果你要运行Java程序,只需要安装JRE;如果需要编写Java程序,安装JDK。
Java基础知识
1. 标识符和关键字
标识符:Java中所有的名字,包括类名、变量名、方法名
- 所有的标识符都应该以字母(A-Z 或者a-z) ,美元符($) 、或者下划线( )开始
- 首字符之后可以是字母(A-Z 或者a-z) ,美元符($) 、下划线( )或数字的任何字符组合
- 不能使用关键字作为变量名或方法名。
- 标识符是大小写敏感的
- 合法标识符举例: age、$salary、 _value、1 value
- 非法标识符举例: 123abc、-salary. #abc
关键字:
不常见:
enum:枚举
final 用来说明最终属性,表明一个类不能派生出子类,或者成员方法不能被覆盖,或者成员域的值不能被改变,用来定义常量
instanceof 用来测试一个对象是否是指定类型的实例对象
strictfp 用来声明FP_strict(单精度或双精度浮点数)表达式遵循IEEE 754算术规范
synchronized 表明一段代码需要同步执行,即锁
transient 声明不用序列化的成员域
volatile 表明两个或者多个变量必须同步地发生变化
1.1 public protected default private区别
作用域 | 当前类 | 同一包下 | 子孙类 | 其他包 |
---|---|---|---|---|
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
default | √ | √ | × | × |
private | √ | × | × | × |
不写的话默认是default
2. Java数据类型
2.1. 基本数据类型
类型 | 字节 | 默认值 | 封装类型 |
---|---|---|---|
byte | 1 | (byte)0 | Byte |
short | 2 | (short)0 | Short |
int | 4 | 0 | Integer |
long | 8 | 0L | Long |
float | 4 | 0.0f | Float |
double | 8 | 0.0d | Double |
boolean | - | false | Boolean |
char | 2 | \u0000(null) | Character |
所有基本数据类型都是存储在栈内存中,所占的存储空间是不变的,都有正负,没有无符号的数据类型。
封装类:泛型类使用的参数是对象类型,无法直接使用基本数据类型,Java提供了封装类。
基本数据类型和封装类的区别:
- 基本类型按值传递,封装类引用传递
- 基本类型在栈创建,封装类的对象在堆中创建,对象的引用在栈创建。
2.2. 引用数据类型
除了基本数据类型,其他的都是引用数据类型,比如String
,其他还有类、接口、数组
2.3. 数据类型的转换
隐式转换和强制转换:
隐式转换:
- 取值范围:byte<short<int<long<float<double
- 什么时候转换:数据类型不一样,不能进行计算,需要转成一样的才可以进行计算
- 转换规则:取值范围小的和范围大的进行运算,小的先提升为大的,再进行运算;
byte、short、char三种类型的数据在运算的时候,都会直接先提升为int,再进行运算
强制转换:
- 把取值范围大的数值赋值给取值范围小的变量,是不允许直接赋值的,如果一定要赋值就需要强制转换
- 在极端值的情况赋值可能会发生错误,因为取值范围不同。
Java的基本数据类型(上表),从左到右可以自动转换,反过来需要强制转换,但会丢失精度或者内存溢出。
3. 变量
变量是存储数据的最小单元,在Java中声明变量的时候必须声明变量的数据类型
//数值类型的不要超出范围。
byteb=127;
short S = 6583;
int i = 6546465;
//如果长整型的数据超出了i nt的范围就需要添加L/1。
1ong
1 = 654656546465L ;
//如果赋值的是小数,就一定要添加F/f表示是f1oat类型
float f = 6546 .10252F;
//所有的小数后面默认添加的就是d/D.
doub1e d =
654.233 ;
//字符型,只能写一一个字符,必须使用'';
charch='男';
//boolean ,只有true或者false , java中的boo lean没有0或者非0的概念。
boolean flag = false;
//字符串的赋值方式,所有的字符串要使用"”
String name = "张三";
- 在Java中申明变量后必须赋值才能使用
- 一个变量在一个作用域中不能申明两次
- 一个变量在一个作用域中可以多次赋值
3.1 常量
常量可以理解成一种特殊的变量,它的值被设定后,在程序运行过程中不允许被改变.
final double PI=3.14;
4. 运算符和表达式
运算符有:赋值运算符(=)、算术运算符(±*/)、关系运算符(><>=<=)、逻辑运算符(&&||)、位运算符(&|>><<)等。
4.1 算数运算符
当字符或数字相加时,通过ASCLL码表查询到对应数字再进行计算
当字符串相加时,所做的不是算数运算,而是将前后的数据进行拼接,产生一个新的字符串。
4.2 自增运算符
++和–既可以放在前面也可以放在后面,区别在于放在后面是先执行再运算,前面是先运算再执行。
4.3 赋值运算符
扩展的赋值运算符隐含了强制类型转换
4.4 关系运算符
4.5 逻辑运算符
逻辑运算符&和|还有相应的短路逻辑运算符,分别是&&和||,&&和&的区别, | |和|的区别:
- &&和&都可以做逻辑运算。
- &&是逻辑与。&是按位与。 可以做位移运算。
- (a && b) :如果a是false ,就不会在运行b了。
- (a & b):无论a是否确定了表达式的结果,都会运行b。
- ||和|是一样的。.
(a || b ) :如果a为true ,就不会再运行b了。
(a | b ):无论如何都会运行b。
4.6 三元运算符
格式:表达式 ? 表达式1 : 表达式2
若表达式为true,表达式1的结果就是运算结果
若表达式为false,表达式2的结果就是运算结果
5. 流程控制
流程控制有:顺序语句、条件语句、循环语句
5.1条件语句
(1)if判断
if....
if...else
if .else if ... else..
tips :
java中if (表达式)这个表达式必须是boolean ,无法自动类型转换。
pub1ic static void main(String[] args) {
intX=10;
if(x>9){
...
}
if(true) {
}
boolean flag = false;
if(flag) {
}
}
(2)switch判断
switch 语句:做等值判断。
switc(表达式){
case 值1:
....
break;
case 值2:
....
break;
default:
....
break;
}
tips:
在JDK1.7之前表达式只能是: byte , short, char , int ,枚举。
在1.7之后加入String
String name = "张三";
switch(name) {
case "张三":
System.out.println("name="+name);
break;
case "李四":
System.out.println("name="+name);
break;
}
(3)循环语句
所有的循环语句和js的循环几乎没有太大的区别。
for循环:
for(条件1;条件2;条件3){
...
}
for(int i=0;i<=10;i++){
...
}
while循环:
wihle(表达式) {
...
}
do{
...
}while(表达式) ;
这里的表达式必须是布尔值。
pub1ic static void main(String[] args) {
intx=0;
while(x < 5) {
System. out . print1n("while循环:"+x);
X++;
}
inty=0;
do {
System. out. print1n("do-whi1 e循环:"+y);
y++;
}while(y<5) ;
for(int z = 0;z<5;z++) {
System. out . print1n("for循环:"+z);
}
while循环的do循环的区别:
while循环先判断在执行,do循环先执行在判断。do循环至少会执行一次循环体。
(4)中断循环
break :跳出整个循环。
continue :中断本次循环,继续下次循环。
return :中断当前正在执行的方法。
6. 数组
6.1 定义
- 数组是相同类型数据的有序集合.
- 数组是Java中的引用数据类型
- 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。
- 其中,每一个数据称作一个数组元素, 每个数组元素可以通过一个下标来访问它们。
6.2 特点
- 数组在堆内存中是一串连续的空间
- 数组的长度是固定的。如果越界,则报: ArrayIndexOutofBounds
- 一个数组中的 所有数据的类型必须是一致的。
数组的申请语法:
//申请数组
int [] nos; //首选方法
String names [];
数组的初始化:所谓初始化,就是在内存中开辟空间
方式:
(1)new数据类型[数组长度]. //tips:长度必须指定。
一旦初始化了数组, jvm就会会在内存中开辟好空间。这些空间都是有默认值的。 这个默认值就是对应的数据类型的默认值。
new int[2]
数据类型 | 默认值 |
---|---|
byte | 0 |
char | ‘\u000’ |
short | 0 |
int | 0 |
long | 0L |
float | 0.0F |
double | 0.0 |
boolean | false |
其他 | null |
(2)在new的同时指定初始值。
new数据类型[]{value1 ,value2,value…valuen};
tips:这种方式初始化数组,绝对不要指定长度。
new int[] {1,2,3}
(3)在申请数组的同时初始化。
数据类型[]数组名= {value1,vale…};
tips :这种方式必须是申请数组的同时初始化。
int[] a = {1,2,3}
6. 3 常见操作
(1)获取数组长度:数组名.length
(2)获取数组中的一个元素:数组名[下标] //不能越界
(3)赋值:数组名[下标] =值
如果要给数组增加一个数据,由于数组的长度无法改变,所以常见的做法就是新建一个数组,将原来的数组拷贝到新数组中,然后新数组要比原来的数组长度多一个。
(4)for循环遍历
6.4 二维数组
二维数组就是每一个元素就是一个数组
二维数组语法:
int [][] a;
a = new int[外部数组的长度,必须有][里面数组的长度,可有可无]
7. 方法
7.1 定义
- Java方法程序中最小的执行单元,它们在一起执行一个功能。
- 方法是解决一类问题的步骤的有序组合
- 方法包含于类或对象中
- 方法在程序中被创建,在其他地方被引用
设计方法的原则:
设计方法的原则:方法的本意是功能块,就是实现某个功能的语句块的集合。我们设计方法的时候,最好保持方法的原子性,就是一个方法只完成1个功能,这样利于我们后期的扩展。
语法:
修饰符 <返回值类型> 方法名称( [参数列表]){
方法体
return 返回值; //返回值为void不需要这句话
}
public static void demo(){
}
- 修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
- 返回值类型:方法可能会返回值。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType 是关键字void。
- 方法名:是方法的实际名称。方法名和参数表共同构成方法签名。
- 参数类型:参数像是-个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
- 形式参数:在方法被调用时用于接收外界输入的数据。
- 实参:调用方法时实际传给方法的数据。
调用方法:对象名.方法名(实参列表)
7.2 关于传参
传参有值传递和引用传递两种情况
值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
所有基本数据类型都是这种方式
package arrayDemo;
public class Demo1 {
public static void main(String[] args) {
int b =20;
change(b);// 实参 实际上的参数
System.out.println(b); //b=20
}
public static void change(int a){//形参 形式上的参数
a=100;
}
}
通俗的讲法就是:形参只是实参创建的一个副本,副本改变了,原本当然不可能跟着改变;
引用传递:引用传递就是直接把内存地址传过去,也就是说引用传递时,操作的其实都是源数据,这样的话修改有时候会冲突,记得用逻辑弥补下就好了,具体的数据类型就比较多了,比如Object,二维数组,List,Map等除了基本类型的参数都是引用传递。
package arrayDemo;
public class Demo1 {
public static void main(String[] args) {
int [] a={1,2,3};
System.out.println(a[0]);
change(a);
System.out.println(a[0]);
}
public static void change(int[] a ){
a[0]=100;
}
}
由于引用传递,传递的是地址,方法改变的都是同一个地址中的值,
原来a[0]指向0x13地址,值是1,
后来在a[0] 指向的也是0x13地址,将值变成了100
所以,再查询a[0]的值的时候,值自然变成了100
7.3 方法的重载
定义: 在同一个类中,定义了多个同名的方法,每个方法具有不同的参数类型和参数个数,这些方法构成了重载的关系。
特点:
- 方法名相同,参数不同
- 参数不用:个数不同、类型不同、顺序不同,与返回值无关
public static sum(int a, int b){
return a + b;
}
//参数顺序不同,构成重载,但是不建议
public static sum(int b, int a){
return a + b;
}
public static sum(int a, int b, int c){
return a + b + c;
}
- ———————————————————————————结尾——————————————————————————————