转载:https://blog.csdn.net/Tracycoder/article/details/105413433
〇、java概述
1.java的优点
- 跨平台:java摆脱了硬件平台的束缚,实现了 “一次编写,到处运行”的理想。
- 它提供了一种相对安全的内存管理和访问机制,避免了绝大部分的内存泄漏和指针越界问题。
- 它实现了热点代码检测和运行时编译及优化,这使得Java应用能随着运行时间的増加而获得更高的性能。
- 它有一套完善的应用程序接口,还有无数的来自商业机构和开源社区的第三方类库来帮助实现各种各样的功能。
- ……
2.java技术体系
(1)JDK
支持Java程序开发的最小环境。JDK = Java程序设计语言+Java虚拟机+Java API类库。
(2)JRE
支持Java程序运行的标准环境。JRE=Java虚拟机 +Java API类库中的Java SE API子集 。
一、标识符
1.什么是标识符
凡是可以由自己命名的地方都称为标识符。例如,对于常量、变量、函数、语句块、类、项目等都需要一个名字,这些我们都统统称为标识符。
2.命名规范
- 标识符有字母、数字、_(下划线)、$所组成,其中不能以数字开头,不能用Java中的保留字(关键字)。
- java中的字母并不只是英文字母,它包括能在某种语言中代表字母的任何Unicode字符。
- 尽管$是一个合法的J&va字符,但不要在你自己的代玛中使用这个字符。它只用 在Java编译器或其他工具生成的名字中。
- 标识符采用有意义的简单命名,没有长度限制。
- 标识符大小写敏感。
- 类名、接口名采用大驼峰;方法名变量名小驼峰;基本类型的常量全部大写,用下划线分割单词。
二、常量与变量
1.变量
声明一个变量后,要用赋值语句显式初始化,使用未被初始化的变量会报错。
变量名和变量的值:
变量名是在变量声明的时候,该名字和内存中的一块地址绑定在一起的,可以通过变量名找到对应的内存区域,也可以通过地址找到内存区域。
变量的值是变量所对应的内存区域内存放的二进制序列。变量的值不会因为变量的类型发生了改变而改变,当变量被转换为对应类型时,内存区域的二进制序列以该类型的形式翻译出来。这也是强制类型转换能够成立的原因。
2.常量
关键字final表示一个变量只能被賦值一次,一旦被赋值之后,就不能够再更改了。
static final修饰符使得一个变量成为类常量。
三、数据类型
1.八大基本类型
(1)整型
前后缀的使用:
- long型L结尾:40000000L
- 十六进制0x开头:0xCAFE
- 八进制0开头:010,容易混淆
- 二进制0b开头:0b1001
- 可以给数字添加下划线,提高可读性:1_000_000
需要注意的是:Java没有任何无符号类型。
(2)浮点型
- 程序中的小数默认为double型,除非添加显式后缀F,也可给小数添加doublede后缀D。
- 可用常量Double.POSITIVE_INFINITY、Double.NEGATIVE_INFINITY、Double.NaN表示三种情况:正无穷、负无穷、非数字,检测方式如下:
- 浮点数值不适用于禁止出现舍入误差的金融计算中,这种情况下可以使用BigDecimal类。这是因为浮点数值采用二进制系统表示,而在二进制系统中无法精确的表示分数1/10。这就好像十进制无法精确地表示1/3—样。
(3)char
在Java中,char类型用UTF-16编码描述一个代码单元。最好不要使用char,因为在极少数的情况下,一个字符需要两个代码单元来表示。
(4)boolean
boolean(布尔)类型有两个值:false和true,用来判定逻辑条件。和C不同,整型值和布尔值之间不能进行相互转换。
2.引用类型
(1)BigInteger、BigDecimal
用类定义的类型称为引用类型,这里介绍两个特别的类——BigInteger和BigDecimal。
如果基本的整数和浮点数精度不能够满足需求,那么可以使用java.math包中的两个很有用的类:BigInteger和BigDecimal。这两个类可以处理包含任意长度数字序列的数值。
Biglnteger类实现了任意精度的整数运算,BigDecimal实现了任意精度的浮点数运算。
(2)String、StringBuilder、StringBuffer
String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,这样不仅效率低下,而且大量浪费有限的内存空间。为了应对经常性的字符串相关的操作,StringBuffer类和StringBuild类用来对此种变化字符串进行处理。
和String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。StringBuilder和StringBuffer之间的最大不同在于StringBuilder的方法不是线程安全的(不能同步访问)。由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。
(3)Date、GregorianCalender
数据库中date类型与datetime类型:
- date类型可用于需要一个日期值而不需要时间部分时。MySQL 以 ‘YYYY-MM-DD’ 格式检索与显示date值。支持的范围是 ‘1000-01-01’ 到’9999-12-31’。
- datetime类型:可用于需要同时包含日期和时间信息的值。MySQL 以 ‘YYYY-MM-DD HH:mm:ss’格式检索与显示 DATETIME 类型。支持的范围是’1000-01-0100:00:00’ 到 ‘9999-12-3123:59:59’。(“支持”的含义是,尽管更早的值可能工作,但不能保证他们均可以。)
(4)枚举类
代码如下:
//简单的写法
Public enum Size{SMALL,MEDIUM,LARGE,EXTRA_LARGE};
//更详细的写法
Public enum Size
{
SMALL("S"),MEDIUM("M"),LARGE("L"),EXTRA_LARGE("XL");
//甚至可以定义域,构造器,get方法等
};
Size s=Size.MEDIUM;
//s只能存储这个类型声明中给定的某个枚举值,或者null值(表示这个变量没有设置任何值)。
- Size的声明定义的类型是一个类,它刚好有4个实例。
- 在比较两个枚举类型的值时,用==,而不需要equals方法。
- 所有的枚举类型都是Enum类的子类,继承了许多方法:toString、valueOf、values、ordinal。
3.包装类型/包装器与自动装箱
(1)包装器
有时,需要将int这样的基本类型转换为对象。所有的基本类型都有一个与之对应的类。例如,Integer类对应基本类型int。通常,这些类称为包装器。这些对象包装器类拥有很鲜明的名字:Integer. Long、Float、 Double、Short、Byte、Character. Void 和 Boolean 。
对象包装器类是不可变的,即一旦构造了包装器,就不允许更改包装在其中的值。同时,对象包装器类还是final,因此不能定义它们的子类。
(2)自动装箱、自动拆箱
假设想定义一个整型数组列表。而尖括号中的类型参数不允许是基本类型。Java集合中实际存放的只是对象的引用,每个集合元素都是一个引用变量,实际内容都放在堆内存或者方法区里面,但是基本数据类型是在栈内存上分配空间的,栈上的数据随时就会被收回的。
这里就用到了 Integer对象包装器类,我们可以声明一个Integer对象的数组列表。如下:
Arraylist<Integer> list = new ArrayList();
- 当调用
list.add(3);
时,将自动地变换成list.add(Integer.valueOf(3));
这种变换被称为自动装箱。 - 相反地,当将一个Integer对象斜一个int值时,将会自动拆箱。也就是说,编译器将
int n=list.get(i);
翻译成int n=list.get(i).intValue();
。 - 甚至在算术表达式中也能够自动地装箱和拆箱。如下所示,可以将自増操作符应用于一个包装器引用,编译器将自动地插入一条对象拆箱的指令,然后进行自増计算,最后再将结果装箱。
Integer n=3;
n++;
四、运算符
1.基本运算符
在Java中,使用算术运算符+、一、*、/表示加、减、乘、除运算。当参与/运算的两个操作数都是整数时,表示整数除法;否则表示浮点除法。整数的求余操作(有时称为取模)用%表示。例如,15/2等于7, 15%2等于1, 15.0/2等于7.5。
2.自增自减
3.关系运算符
- == !=
- < > <= >=
- && || :短路设计
- !
- 三目运算符
4.位运算
- &:与
- | :或
- ~:非
- ^:异或
- <<:二进制位左移
- >> >>>:二进制位右移,>>运算符将用0填充高位,>>>用符号位填充高位。
&、|与&&、||:
&和I运算符应用于布尔值,得到的结果也是布尔值。这两个运算符与&&和II的运算非带类似,只是不按“短路”方式计算。即在得到计算结果之前,一定要计算两个操作数的值。
5.数学函数与常量
在Math类中,包含了各种各样的数学函数和常量。
常见的函数有:求平方根sqrt(),幂运算pow()等。
常见的常量如下:
6.强制类型转换
强制类型转换采用截断式取值,有可能会发生精度的损失。
五、流程控制语句
- Java没有goto句,但break语句可以带标签,可以利用它实现从内层循环跳出的目的。如果输入有误,通过执行带标签的break跳转到带标签的语句块末尾。
- for each循环,适用于遍历数组或容器的元素,并且不需要获取下标值。
六、方法
方法内部不能定义方法。
1.静态方法
静态方法是一种不能向对象实施操作的方法,它没有隐式参数。因为静态方法不能操作对象,所以不能在静态方法中访问实例域。但是,静态方法可以访问自身类中的静态域。
在下面两种情况下使用静态方法:
- 一个方法不需要访间对象状态,其所需参数都是通过显式参数提供。
- 一个方法只需要访问类的静态域。
2.main方法
每一个类都可以有一个main方法,可以更好地进行单元测试。
3.方法参数
按值调用(call by value)表示方法接收的是调用者提供的值。而按引用调用(call by inference)表示方法接收的是调用者提供的变量地址。一个方法可以修改传递引用所对应的变量值,而不能修改传递值调用所对应的变量值。
Java程序设计语言总是采用按值调用。也就是说,方法得到的是所有参教值的一个拷贝,特别是,方法不能修改传递给它的任何参数变量的内容。
(1)传入参数是基本类型
可以看到,无论怎样,调用这个方法之后,percent的值还是10。
下面看一下具体的执行过程:
- ①x被初始化为percent值的一个拷贝(也就是10)。
- ②x被乘以3后等于30,但是percent仍然是10。
- ③这个方法结束之后,参数变量x不再使用。
(2)传入参数是引用类型
具体的执行过程为:
- ①x被初始化为harry值的拷贝,这里是一个对象的引用。
- ②raiseSalary方法应用于这个对象引用。x和harry同时引用的那个Employee对象的薪 金提高了 200%。
- ③方法结束后,参数变最x不再使用。当然,对象变量harry继续引用那个薪金増至3 倍的雇员对象。
下面总结一下Java程序设计语言中方法参数的使用情况:
- 一个方法不能修改一个基本数据类型参数(即数值型和布尔型)。
- 一个方法可以改变一个对象参数的状态。
- 一个方法不能让对象参数引用一个新的对象。
4.“变参”方法
下面是一个简单的示例:
public static double max(double...values){
double largest=Double.MIN_VALUE;
for(double v:values)if(v>largest)largest=v;
return largest;
}
可以传入多个double型的参数,系统会将它们视为一个double[]数组,也可以直接传入一个double[]数组。
七、注释
以/** 开始,以 */结尾的注释可以自动地生成文档。
1.类注释
类注释在import语句之后,类定义之前。
2.方法注释
放在方法之前。
- @param变量描述
- @return返回描述
- @throws表明方法可能抛出异常
3.域注释
只需要对公有域(通常指静态常量)建立文档。
4.通用注释
- @author姓名 作者条目
- @version文本 版本
- @since文本 始于
- @deprecated文本 弃用
- @see 引用
5.包与概述注释
需要单独的文件。
八、数组
- 一旦创建了数组,就不能再改变它的大小。
- 数组长度为0和null不同。
- 在Java中,允许将一个数组变量拷贝给另一个数组变量。这时,两个变量将引用同一个数組.
九、关键字
十、Lambda
1.特点
- 匿名:没有一个确定的名称。
- 函数:lambda不属于一个特定的类,但是却有参数列表、函数主体、返回类型、异常列表。
- 传递:可以作为参数传递给方法、或者存储在变量中。
- 简洁:不需要写很多模板代码。
1.基本语法
//expression是返回类型
(parameters) -> expression
//statements是一些操作,可以有return语句
(parameters) -> {statements;}
(parameters) -> statement;
2.在哪里使用lambda——函数式接口
只有在接受函数式接口的地方才可以使用Lambda表达式。所谓函数式接口,是指只定义一个抽象方法的接口。
下面哪些接口是函数式接口?
//1
public interface Adder{
int add(int a, int b);
}
//2
public interface SmartAdder extends Adder{
int add(double a, double b);
}
//3
public interface Nothing{
}
//答案:只有Adder是函数式接口。
//SmartAdder不是函数式接口,因为它定义了两个叫作add的抽象方法(其中一个是从Adder那里继承来的)。
//Nothing也不是函数式接口,因为它没有声明抽象方法。
lambda可以使得代码更为简洁:
Runnable r1 = () -> System.out.println("Hello World 1");
Runnable r2 = new Runnable(){
public void run(){
System.out.println("Hello World 2");
}
};
public static void process(Runnable r){
r.run();
}
process(r1);
process(r2);
process(() -> System.out.println("Hello World 3"))