基本语法
1.在逻辑运算中存在一个短路特性
①对于逻辑与运算符来说,若第一个表达式为假则结果为假,此时跳过第二个表达式;
②对于逻辑或运算符来说,若第一个表达式为真则结果为真,此时跳过第二个表达式
2.赋值表达式返回(eg:a=5)的值为5;
3.两个byte变量相加,会自动转换为int类型,byte+int也会自转为int,所以如果继续使用byte类型,需要进行括号强行转换。(使用+=运算符时,会自动再强行转换为byte)。
4.java中可用变长的方法参数
//自定义可变长参数的使用 看作为一维数组即可
void showArgument(String... args){
for(int i =0;i<args.length;i++){
System.out.println("第"+(i+1)+"个参数为:"+ args[i])
}
}
5.数组是引用型,但凡是引用型变量,变量(地址)存在栈中,数组内容存在堆中
java面向对象编程
-
static修饰的静态成员为类层级,整个类只有此一份且被所有对象共享,随着类的载入即载入,在方法区;
-
当需要在执行构造方法体之前做一些准备工作时,则将准备工作的相关代码写在构造块中即可,比如:对成员变量进行的统一的初始化操作,每创建一个对象的时候都会执行一次代码块(普通)。
-
静态代码块:只执行一次(接上)。
-
单例设计模式的实现流程(一):尽量用饿汉式(在类中就创建一个对象)
①私有化构造方法,使用private关键字修饰。
②声明本类类型的引用指向本类类型的对象,并使用private static关键字共同修饰。
③提供共有的get方法负责将对象返回出去,并使用public static 关键字共同修饰 -
子类可以继承父类的私有变量,但是不能直接访问,需要调用父类的get set方法进行访问;
-
无论用何种方法构造子类对象时,都会自动调用父类的无参构造方法,也可以手动加上super()代替这个功能;因为构造完整的子类对象必须先构造完整的父类方法。
-
调用父类的方法,使用super.函数名();
-
重写父类方法时,子类方法访问权限至少相同或者扩大,要求不能抛出更大的异常,使用重写的方法时,编译阶段调用父类方法,执行阶段调用子类方法
-
类中代码块也被称作构造块,父类和子类同时具有静态代码块时,先执行父类静态代码块——>子类静态代码块 ——>父类普通代码块——>子类普通代码块
-
public static final 修饰常量,final修饰的类 无法被继承,final修饰的方法无法被重写;
-
多态(屏蔽不同子类的差异性)(声明方法为 :父name xx= new 子name ):①子类重写了方法时,代码在编译阶段调用父类的方法,在运行阶段调用子类的方法。②用父类接收子类对象时,只能调用父类存在的方法。③对于父类子类都有的静态方法来说,编译和运行阶段都调用父类方法
-
引用数据类型之间的转换
• 若强转的目标类型并不是该引用真正指向的数据类型时则编译通过,运行阶段发生类型转换异常。
• 为了避免上述错误的发生,应该在强转之前进行判断,格式如下:
if(引用变量 instanceof 数据类型)
判断引用变量指向的对象是否为后面的数据类型 -
抽象类和抽象方法:①抽象类中可以有成员变量、构造方法、成员方法,可以没有抽象方法,但抽象方法(没有方法体)必须在抽象类中。②真正意义上的抽象类,是拥有抽象方法的用Abstract修饰的类;
-
在以后的开发中推荐使用多态的格式,此时父类类型引用直接调用的所有方法一定是父类中拥有的方法,若以后更换子类时,只需将new关键字后面的子类类型修改。但父类引用若要调用子类独有的方法,则需要强制类型转换。
-
抽象类和private、final不可以共存。
-
接口:①比抽象类还要抽象,所有方法都是抽象方法,所有变量必须使用static(默认) final 修饰,也就是说只能用常量,允许出现私有方法;
java8以后
②接口中可以增加默认方法 public default void test(…){ …},让子类决定是否重写;
③接口中可以添加静态方法,public static void test(…){…},使用 接口名.test() 来使用;
java9以后
④接口中允许出现私有方法(方便代码的复用)
接口只能继承接口 -
类中的内容有(成员变量、成员方法、构造方法、静态成员、构造块和静态代码块,内部类)
内部类(顾名思义,是在类的内部创建的类):①普通内部类(成员内部类) 属于外部类的成员,并且是对象层级,调用方法如下:
NormalOuter no = new NormalOuter();
NormalOuter.NormalInner ni = no.new NormalInner();
普通内部类需要使用外部类对象来创建对象,如果内部类和外部类有同样的成员变量名,内部类中访问内部类关键字需要使用this.成员名,如果访问外部的同名成员,需要使用 OutName.this.成员名
②静态内部类:使用static 关键字修饰的内部类,隶属于类层级
静态内部类访问内部类的同名成员可使用 InName.成员名
访问外部类中的同名成员使用 OutName.成员名
③局部内部类:直接将一个类的定义放在方法提的内部
若要使用的话,在方法体内部直接创造对象,局部内部类不能使用控制访问符和static修饰。局部内部类使用外部方法的局部变量时,只能使用final的,因为局部内部类是拷贝一份使用
④匿名内部类:没有名字的内部类,是特殊的局部内部类,本身局部内部类存在的目的就是为了得到一个类或者接口的子类对象,这时候类叫什么其实不重要了,于是出现了匿名内部类。
使用匿名内部类的语法格式是:
接口/父类类型 引用变量名 = new 接口/父类类型 {
//上面类或者接口的子类的类体
//这是A1类的子类类体,可以重写父类方法,也可以新增自己的成员
};
解释:
1.new关键字表示创建对象,所以该匿名内部类语法,整体表示一个对象,而不是一个类。
2.整个语法表示的对象,是语法中写的类名/接口名的子类对象,所以匿名内部类蕴含了继承或者实现。
3.整个语法表示创建子类对象,但是这个子类我们不知道他叫什么,所以这个语法叫:匿名(子类的)内部类(对象)
4.类名可以是普通类,也可以是抽象类
匿名内部类的使用方法:1,使用引用接受。2直接调用方法,访问成员
- Lambda表达式简化接口的匿名内部类,,必须要求这个接口是功能接口(Functional Interface)(接口中有且只有一个必须要求子类实现的抽象方法的接口)
功能接口使用注解@FunctionalInterface标记,该注解可以标记和检验一个接口是否是功能接
①功能接口中是否只能由一个方法呢? 并不是,java8中还有默认方法和静态方法,不需要子类实现。
②功能接口中只能由一个抽象方法吗?并不是,
Lambda表达式语法: () ->{}
解释:():是功能接口中那个必须实现的抽象方法的形参列表。
->:是一个箭头,是Lambda表达式的运算符,可以读作“goes to”。
{}:是功能接口中必须要实现的抽象方法的重写方法体
注意:因为Lambda表达式只有一套用于方法重写,只能重写一个方法,所以一定要注意 {} 内是方法体,不是类体,这意味着Lambda表达式虽然指标是一个接口的子类对象,但是这个对象一定没有自身独有的成员,因为没有办法定义,这里即使定义了也是方法体内的局部变量
lambda表达式的实现方式:
①直接用父接口引用接受
②使用 ((父接口的名字)lambda表达式). 方法名(实参列表);
③借助方法的返回值类型完成类型推断 / 借助方法的形参数据类型完成类型推断
- 枚举 :①枚举值就是当前类的类型,这就是指向本类的对象,默认使用public static final关键字修饰,因此采用枚举类型.的方式调用。②枚举类可以自定义构造方法,但是构造方法的修饰必须是private,默认也是私有的。
枚举的对象实例生命在枚举内,一般使用简化的写法 eg:UP(“上”)
而实际完成的写法为 public static final Direction UP = new Direction("上")
枚举类使用的方法
方法名 | 功能 |
---|---|
String toString() | 返回当前枚举类对象的名称 |
static T[] values() | 返回当前枚举类中的所有对象 |
int ordinal() | 获取枚举对象在枚举类中的索引位置 |
static T valueOf(String str) | 将参数指定的字符串名转为当前枚举类的对象 |
int compareTo(E o) | 比较两个枚举对象在定义时的相对顺序= 该枚举序号 - E o |
打印引用对象时,会自动调用toString方法
- 枚举类实现接口(
public enum Direction implements DirectionInterface
)的方式有两种,第一种是在该枚举类的内部声明方法,使用例如
@Override
public void show() {
System.out.println("现在可以实现接口中抽象方法的重写了");
}
第二种则是每个枚举类对象都实现方法的重写
public enum Direction implements DirectionInterface {
UP("上"){
@Override
public void show() {
System.out.println("贪吃蛇向上移动一下");
}
},DOWN("下") {
@Override
public void show() {
System.out.println("贪吃蛇向下移动一下");
}
},LEFT("左") {
@Override
public void show() {
System.out.println("贪吃蛇向左移动一下");
}
},RiGHT("右") {
@Override
public void show() {
System.out.println("贪吃蛇向右移动一下");
}
};
private String s1 ;
private Direction(String s) {
s1 = s;
}
public String getS1(){
return s1;
}
- 注解(类似于超市里商品的标签)用法如下:
fang
所有注解都继承java.lang.annotation
java核心类库
- Object类为所有类的父类,如果要使用Object类中的方法(比如equal,toString)需要重写,object类中是没有成员变量定义的,并且由于子类对象的隐式初始化,Object类中仅有一个默认提供的无参构造方法。因此主要学习成员方法
//当student重写object的方法后
@Override
public boolean equals(Object obj) {
//当调用对象不为空而参数对象为空时,则内容一定相同
if (this == obj) return true;
//当调用对象不为空, 而参数对象为空时,内容不一定相同
if (null == obj)
return false;
//判断obj是否为Student类型的变量,若是,则条件成立
if (obj instanceof Student) {
Student st = (Student) obj;
return this.getId() == st.getId();
}
//否则类型不一致,没有可比性,则内容一定不相同
return false;
}
- 常用的方法
方法声明 | 功能介绍 |
---|---|
Object() | 使用无参方式构造对象 |
boolean equals(Object obj) | 用于判断调用对象是否与参数对象相等。该方法默认比较两个对象的地址是否相等,与 == 运算符的结果一致。若希望比较两个对象的内容,则需要重写该方法。若该方法被重写后,则应该重写hashCode方法来保证结果的一致性。 |
int hashCode() | 同getClass一样是一个本地方法,没有方法体。①用于获取调用对象的哈希码值(内存地址的编号),该方法表示一种哈希印射的规则。 ②若两个对象调用equals方法相等,则各自调用该方法的结果必须相同。③若两个调用对象equals方法不相等,则各自调用该方法的结果应该不相同。④为了使得该方法与equals方法保持一致,需要重写该方法。 |
String toString() | ①用于获取调用对象的字符串形式。②该方法默认返回的字符串为:包名.类名@哈希码值的十六进制。③为了返回更有意义的数据,需要重写该方法 。④使用print或println打印引用或字符串拼接引用都会自动调用该方法 |
public final native Class<?> getClass(); | 用于返回调用对象执行时的Class实例,反射机制使用,native代表是本地方法,不用关注它的实现,这里返回的Class对象是在类加载过程中jvm自动创建的,用于帮助程序员区分类型信息,Class对象也叫做运行时类对象,用Class引用接收。Class有方法getName()、getName() |
protected Objec clone() | 克隆,得到一个新的对象,全新的一种创建对象的方式,java中,要对一个对象进行克隆操作,这个对象的类型必须实现接口Cloncable。clone()会得到一个完全独立的新对象(类型一致,变量成员相同)。clone() 一般不需要重写 ;Object中的clone是浅拷贝,拷贝出新的对象中的引用类型和原对象还是指向同一片区域,只有基本数据类型是新的变量。若需要深度拷贝,则需要将拷贝对象的引用对象也克隆一次,在浅克隆基础上完成的 |
深度克隆的方法
- Integer类的常用方法
static Integer valueOf(int i) | 根据参数指定整数值得到Integer类型对象 |
---|---|
int intValue() | 获取调用对象中的整数值并返回 |
static int parseInt(String s) | 将字符串类型转换为int类型并返回 |
static String toString(int i) | 获取参数指定整数的十进制字符串形式 |
static String toHexString(int i) | 获取参数指定整数的十六进制字符串形式 |
- Integer类中 -127~128已经装箱(作为类存在)
- Double类中有个Integer中没有的方法 : boolean isNaN() 用以判断调用对象的数值是否为非数字
- 所有数据类的父类为Number
- Character类有以下常用方法,上述类在java5后已经实现了自动装箱和拆箱(也就是可以由基本类型和类相互转换)
方法声明 | 功能介绍 |
---|---|
char charValue() | 获取调用对象中的字符数据并返回 |
static Character valueOf(char c) | 根据参数指定字符数据得到Character类型对象 |
boolean equals(Object obj) | 比较调用对象与参数指定的对象是否相等 |
String toString() | 返回描述调用对象数值的字符串形式 |
static boolean isUpperCase(char ch) | 判断参数指定字符是否为大写字符 |
static boolean isDigit(char ch) | 判断参数指定字符是否为数字字符 |
static char toUpperCase(char ch) | 将参数指定的字符转换为大写字符 |
-
包装类(Wrapper)的使用总结
基本数据类型转换为对应包装类的方式:调用包装类的构造方法或静态方法即可
获取包装类对象中基本数据类型变量数值的方式:调用包装类中的xxxValue方法即可
字符串转换为基本数据类型的方式:调用包装类中的parseXxx方法即可 -
Math类中各种算数的静态方法
-
在进行浮点数运算时,可能会遇到运算结果不太精确的问题, 这时候使用BIgDecimal类来实现精确运算,所蕴含的静态方法有add(b1)、subtract(b2)、multiply(b3)、divide(b4)、
-
String 类是可以new创建又可以直接字符串赋值的特殊类,jvm虚拟机会将第一次出现的字符串给放置到常量池内,需要的时候会调用。
-
String类的笔试考点:①String有两种构造方法,直接赋值和new
String str1 = "abc" ; //创建了一个对象,存放在常量池中
String str2 = new String("abc"); //创建了2 个对象,一个在常量池,一个在堆区
byte[] bArr = {97,127,12,55,43};
String str3 = new String(bArr,1,3);//通过byte数组来生成字符串
②整数类型转化为String类型
String.valueOf( num);
或者 str = " "+ num;
③将字符串String转化为整数型
String str1 = new String("123456");
//方法一,使用Integer.paseInt()
int ia = Integer.parseInt(str1);
//方法二:使用ASCII来实现类型转换并打印
// '1' - '0' =>1 ------ 字符转换为数字
int ib =0;
//将str1的数字拆开,分贝转换为字符再转换为数字
for(int i =0;i<str1.length(),i++){
ib = ib*10+(str2.charAt(i) - '0');
}
- String类的常用基本方法(自)
方法声明 | 功能介绍 |
---|---|
String toString() | 返回字符串本身 |
byte[] getBytes() | 将当前字符串内容转换为byte数组并返回 |
char[] toCharArray() | 用于将当前字符串内容转换为char数组并返回 |
char charAt(int index) | 方法charAt用于返回字符串指定位置的字符。 |
int length() | 返回字符串字符序列的长度 |
boolean isEmpty() | 判断字符串是否为空 |
不同声明的区别
- String类与其他String类的基本方法
方法声明 | 功能介绍 |
---|---|
int compareTo(String anotherString) | 用于比较调用对象和参数对象的大小关系 |
int compareToIgnoreCase(String str) | 不考虑大小写,也就是’a’和’A’是相等的关系 |
String concat(String str) | 实现字符串的拼接 |
boolean contains(CharSequence s) | 用于判断当前字符串是否包含参数指定的内容 |
String toLowerCase() | 返回字符串的小写形式 |
String trim() | 返回去掉前导和后继空白的字符串 |
boolean startsWith(String prefix) | 判断字符串是否以参数字符串prefix开头 |
boolean startsWith(String prefix, int toffset) | 从指定位置toffset开始是否以参数字符串prefix开头 |
boolean endsWith(String suffix) | 判断字符串是否以参数字符串suffix结尾 |
boolean equals(Object anObject) | 用于比较字符串内容是否相等并返回 |
int hashCode() | 获取调用对象的哈希码值 |
boolean equalsIgnoreCase(String anotherString) | 用于比较字符串内容是否相等并返回,不考虑大小写,如:'A’和’a’是相等 |
int indexOf(int ch) | 用于返回当前字符串中参数ch指定的字符第一次出现的下标 |
int indexOf(int ch, int fromIndex) | 用于从fromIndex位置开始查找ch指定的字符 |
int indexOf(String str, int fromIndex) | 表示从字符串的fromIndex位置开始检索str第一次出现的位置 |
int lastIndexOf(int ch) | 用于返回参数ch指定的字符最后一次出现的下标 |
随机生成一个字符串的方法
自然排序
1.Comparable接口:
-
实现此接口的类,其对象数组(array)或对象容器(collection),就可以通过 Arrays.sort() 或 Collections.sort() 进行自动排序,需要重写comparaTo方法。
-
对于实现该接口的A类来说,其对象a1.compareTo(a2)方法返回值
-
小于0,表示a1对象小于a2,在自然排序中处于前面的位置
-
大于0,表示a1对象大于a2,在自然排序中处于后面的位置
-
等于0,表示a1对象等于a2
2.Comparator接口:
在排序时需要注意一个比较特殊的方法,带比较器的Arrays.sort方法,即sort(T[] a, Comparator<? super T> c) ,会根据指定比较器产生的顺序对指定对象数组进行排序。其中Comparator接口的实现类对象就是比较器,该对象通过compare方法传入比较的规则。
表示传入比较规则的int compare(T o1, T o2)方法:
该方法可以看成是o1-o2,如果方法返回负数,o1< o2,相反则大于,只有当方法返回0时,才表示对象相等
Collection 集合 1. 集合的用处:当需要在Java程序中记录多个类型不同的对象数据时,则准备一个集合。
2. 集合的框架分类:初期主要学习两种,①Collection ②Map 3. 接口除了上图中根节点的类,其他的都是接口类型,无法实例化,只能用接口类型的引用指向实现类的对象,形成多态。
3. 打印集合中的所有元素时,本质上就是打印集合中的每个对象,让每个对象调用自己的toString方法。
4. Collection中的常用方法
方法声明 | 功能介绍 |
---|---|
c1.add(“one”); | 向集合中添加对象 |
boolean addAll(Collection<? extends E> c) | 用于将参数指定集合c中的所有元素添加到当前集合中 |
boolean contains(Object o); | 判断是否包含指定对象,比较的方式是 拿着参数对象o与集合中的元素一个个进行比较,比较方法调用Objects.equals(o,e) |
boolean containsAll(Collection<?> c) | 判断是否包含参数指定的所有对象 |
boolean retainAll(Collection<?> c) | 保留当前集合中存在且参数集合中存在的所有对象 |
Collection 集合
-
集合的用处:当需要在Java程序中记录多个类型不同的对象数据时,则准备一个集合。
-
集合的框架分类:初期主要学习两种,①Collection ②Map
-
接口除了上图中根节点的类,其他的都是接口类型,无法实例化,只能用接口类型的引用指向实现类的对象,形成多态。
-
打印集合中的所有元素时,本质上就是打印集合中的每个对象,让每个对象调用自己的toString方法。
-
Collection中的常用方法
方法声明 | 功能介绍 |
---|---|
c1.add(“one”); | 向集合中添加对象 |
boolean addAll(Collection<? extends E> c) | 用于将参数指定集合c中的所有元素添加到当前集合中 |
boolean contains(Object o); | 判断是否包含指定对象,比较的方式是 拿着参数对象o与集合中的元素一个个进行比较,比较方法调用Objects.equals(o,e) |
boolean containsAll(Collection<?> c) | 判断是否包含参数指定的所有对象 |
boolean retainAll(Collection<?> c) | 保留当前集合中存在且参数集合中存在的所有对象 |
boolean remove(Object o); | 从集合中删除对象 |
boolean removeAll(Collection<?> c) | 从集合中删除参数指定的所有对象 |
void clear(); | 清空集合 |
int size(); | 返回集合的容量 |
boolean isEmpty(); | 判断是否为空 |
boolean equals(Object o) | 判断是否相等 |
int hashCode() | 返回该集合的哈希码值 |
Object[] toArray() | 将集合转换为数组 |
Iterator iterator() | 获取当前集合的迭代器 |
24.for each循环用于应用数组和集合的遍历。
25.在List集合中,用subList方法取的子集合,其指向的空间就是父集合之中,公用同一块内存空间
26.List集合使用add方法添加新的元素时,会最先申请一个10个空间的一维数组,扩容的原理是每次扩大为1.5倍