基础语法
基本数据类型(熟悉)
Java有哪些数据类型
定义:Java语言是强类型语言,对于每一种数据都定义了明确的具体的数据类型,在内存中分配了不同大小的内存空间。
boolean类型占多少个字节?
- boolean类型被编译为int类型,等于是说JVM里占用字节和int完全一样,int是4个字节,于是boolean也是4字节
- boolean数组在Oracle的JVM中,编码为byte数组,每个boolean元素占用8位=1字节(待考证)boolean数组在非Oracle JVM里面,占用字节数也许不是1字节
jdk8的官方文档解释
虽然Java虚拟机定义了一个boolean类型,但它只为它提供了非常有限的支持。没有Java虚拟机指令专门用于对boolean值的操作。相反,Java编程语言中对boolean值进行操作的表达式被编译为使用Java虚拟机int数据类型的值。
Java虚拟机直接支持boolean数组。它的newarray指令可以创建boolean数组。使用byte数组指令baload和bastore访问和修改类型为boolean的数组。
在Oracle的Java虚拟机实现中,Java编程语言中的boolean数组被编码为Java虚拟机byte数组,每个布尔元素使用8位。
Java虚拟机使用1表示boolean数组组件的true,0表示false。其中Java编程语言布尔值由编译器映射到Java虚拟机类型int的值,编译器必须使用相同的编码。
变量类型(熟悉)
访问修饰符(熟悉)
1、访问修饰符定义
Java中,可以使用访问修饰符来保护对类、变量、方法和构造方法的访问。Java 支持 4 种不同的访问权限。
2、访问修饰符分类
private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
default (即缺省,什么也不写,不使用任何关键字): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
protected : 对同一包内的类和不同包的所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
public : 对所有类可见。使用对象:类、接口、变量、方法
3、访问修饰符图
面向对象
抽象
抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么。
封装
封装把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法,如果属性不想被外界访问,我们大可不必提供方法给外界访问。但是如果一个类没有提供给外界访问的方法,那么这个类也没有什么意义了。
专业描述:【隐藏对象的属性和实现细节,仅对外提供公共访问方式,将变化隔离,便于使用,提高复用性和安全性。】
继承
继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。通过使用继承我们能够非常方便地复用以前的代码。
关于继承如下 3 点请记住:
1、子类拥有父类非 private 的属性和方法。
2、子类可以拥有自己属性和方法,即子类可以对父类进行扩展。
3、子类可以用自己的方式实现父类的方法(重写)。
多态
所谓多态就是指一个引用变量到底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。
专业描述:【父类或接口定义的引用变量可以指向子类或具体实现类的实例对象。提高了程序的拓展性。】
在Java中有两种形式可以实现多态:继承(子类对父类同一方法的重写)和接口(实现接口并覆盖接口中同一方法)。
方法重载(overload)实现的是编译时的多态性(也称为前绑定)
方法重写(override)实现的是运行时的多态性(也称为后绑定)。
重载(Overload)和重写(Override)的区别?
- 方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。
- 重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;
- 重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的参数列表和返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。
- 重载对返回类型没有特殊的要求,不能根据返回类型进行区分。重写要求和父类被重写的方法有相同的返回类型
内部类的分类有哪些?
内部类可以分为四种:成员内部类、局部内部类、匿名内部类和静态内部类。
1、静态内部类
定义在类内部的静态类,就是静态内部类。
public class Outer {
private static int radius =1;
//静态内部类
static class StaticInner{
public void visit(){
System.out.println("visit outer static variable:"+ radius);
}
}
}
静态内部类可以访问外部类所有的静态变量,但是不可访问外部类的非静态变量;
静态内部类的创建方式,new 外部类.静态内部类(),如下:
Outer.StaticInner inner =new Outer.StaticInner();
inner.visit();
2、成员内部类
定义在类内部,成员位置上的非静态类,就是成员内部类。
public class Outer {
private static int radius =1;
privateint count =2;
class Inner{
public void visit(){
System.out.println("visit outer static variable:"+ radius);
System.out.println("visit outer variable:"+ count);
}
}
}
成
成员内部类可以访问外部类所有的变量和方法,包括静态和非静态,私有和公有。
成员内部类依赖于外部类的实例,它的创建方式外部类实例.new 内部类(),如下:
Outer outer =new Outer();
Outer.Inner inner = outer.new Inner();
inner.visit();
3、局部内部类
定义在方法中的内部类,就是局部内部类。
public class Outer{
private int out_a =1;
private static int STATIC_b =2;
public void test FunctionClass(){
int inner_c=3;
class Inner{
private void fun(){
System.out.println(out_a);
System.out.println(STATIC_b);
System.out.println(inner_c);
}
}
Inner inner =new Inner(); //直接在方法里用new创建局部内部类
inner.fun();
}
public static void test StaticFunctionClass(){
int d=3;
class Inner{
private void fun(){
//System.out.println(out_a);
//编译错误,定义在静态方法中的局部类不可以访问外部类的实例变量
System.out.println(STATIC_b);
System.out.println(d);
}
}
Inner inner =new Inner(); //直接在方法里用new创建局部内部类
inner.fun();
}
}
定义在实例方法中的局部类可以访问外部类的所有变量和方法,定义在静态方法中的局部类只能访问外部类的静态变量和静态方法 。
局部内部类的创建方式 ,在对应方法内 new 内部类(), 如下 :
public static void testStaticFunctionClass(){
class Inner{}
Inner inner =new Inner();
}
4、匿名内部类
匿名内部类就是没有名字的内部类
匿名内部类举例
红色框画出来的就是一个匿名内部类同时重写了父类Animals的eat方法,并且调用了这个匿名内部类的eat方法
如何调用匿名内部类中的方法?
1、匿名内部类中只有一个方法的情况
2、匿名内部类有多个方法
第一种方式
第二种方式
如果想调用匿名内部类自己特有的方法的时候呢?该如何调用呢?
匿名内部类可以有自己特有的方法,但是前提条件是这个匿名内部类只有这一个方法(不重写父类或者接口的方法)。如果有多个方法的时候,他只能继承父类的方法以及重写这个方法或实现接口,绝不可能在在多个方法的情况下,调用自身特有的方法,但是这个特有的方法可以存在,但无法调用
匿名内部类是实现接口
匿名内部类存在的前提是要有继承或者实现关系的,但是并没有看到extends和implements关键字,这是怎么回事呢?
答:很简单,匿名内部类没有连类名都没有,使用关键字就更无从说起了。这些由jvm搞定了。
匿名内部类的特点
除了没有名字,匿名内部类还有以下特点:
1、匿名内部类必须继承一个抽象类或者实现一个接口。
2、匿名内部类不能定义任何静态成员和静态方法。
3、匿名内部类访问局部变量的时候,必须把局部变量声明为 final。
4、匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。
匿名内部类创建方式:
new 类/接口{
//匿名内部类实现部分
}
什么是枚举?
枚举是一个被命名的整型常数的集合,用于声明一组带标识符的常数。枚举在曰常生活中很常见,例如一个人的性别只能是“男”或者“女”,一周的星期只能是 7 天中的一个等。类似这种当一个变量有几种固定可能的取值时,就可以将它定义为枚举类型。任意两个枚举成员不能具有相同的名称,且它的常数值必须在该枚举的基础类型的范围之内,多个枚举成员之间使用逗号分隔。
提示:如果没有显式地声明基础类型的枚举,那么意味着它所对应的基础类型是 int。
下面代码定义了一个表示性别的枚举类型 SexEnum 和一个表示颜色的枚举类型 Color。
public enum SexEnum {
male,female;
}
public enum Color {
RED,BLUE,GREEN,BLACK;
}
之后便可以通过枚举类型名直接引用常量,如 SexEnum.male、Color.RED。
枚举类
Java 中的每一个枚举都继承自 java.lang.Enum 类。当定义一个枚举类型时,每一个枚举类型成员都可以看作是 Enum 类的实例,这些枚举成员默认都被 final、public、 static 修饰,当使用枚举类型成员时,直接使用枚举名称调用成员即可。
所有枚举实例都可以调用 Enum 类的方法,常用方法如表 1 所示。
1、通过调用枚举类型实例的 values( ) 方法
可以将枚举的所有成员以数组形式返回,也可以通过该方法获取枚举类型的成员。
下面的示例创建一个包含 3 个成员的枚举类型 Signal,然后调用 values() 方法输出这些成员。
enum Signal {
// 定义一个枚举类型
GREEN,YELLOW,RED;
}
public static void main(String[] args) {
for(int i = 0;i < Signal.values().length;i++) {
System.out.println("枚举成员:"+Signal.values()[i]);
}
}
输出结果如下:
枚举成员:GREEN 枚举成员:YELLOW 枚举成员:RED
2、创建一个示例,调用valueOf() 方法
获取枚举的一个成员,再调用 compareTo() 方法进行比较,并输出结果。具体实现代码如下:
public class TestEnum {
public enum Sex {
// 定义一个枚举
male,female;
}
public static void main(String[] args) {
compare(Sex.valueOf("male")); // 比较
}
public static void compare(Sex s) {
for(int i = 0;i < Sex.values().length;i++) {
System.out.println(s + "与" + Sex.values()[i] + "的比较结果是:" + s.compareTo(Sex.values()[i]));
}
}
}
上述代码中使用 Sex.valueOf("male") 取出枚举成员 male 对应的值,再将该值与其他枚举成员进行比较。最终输出结果如下:
male与male的比较结果是:0 male与female的比较结果是:-1
3、通过调用枚举类型实例的ordinal() 方法
可以获取一个成员在枚举中的索引位置。下面的示例创建一个包含 3 个成员的枚举类型 Signal,然后调用 ordinal() 方法输出成员及对应索引位置。
public class TestEnum1 {
enum Signal {
// 定义一个枚举类型
GREEN,YELLOW,RED;
}
public static void main(String[] args) {
for(int i = 0;i < Signal.values().length;i++) {
System.out.println("索引" + Signal.values()[i].ordinal()+",值:" + Signal.values()[i]);
}
}
}
输出结果如下:
索引0,值:GREEN 索引1,值:YELLOW 索引2,值:RED
集合与泛型
ArrayList的使用
ArrayList 是一个数组队列,相当于 动态数组。与Java中的数组相比,它的容量能动态增长。它继承于AbstractList,实现了List, RandomAccess, Cloneable, java.io.Serializable这些接口。
ArrayList 继承了AbstractList,实现了List。它是一个数组队列,提供了相关的添加、删除、修改、遍历等功能。
ArrayList 实现了RandmoAccess接口,即提供了随机访问功能。RandmoAccess是java中用来被List实现,为List提供快速访问功能的。在ArrayList中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。稍后,我们会比较List的“快速随机访问”和“通过Iterator迭代器访问”的效率。
ArrayList 实现了Cloneable接口,即覆盖了函数clone(),能被克隆。
ArrayList 实现java.io.Serializable接口,这意味着ArrayList支持序列化,能通过序列化去传输。
和Vector不同,ArrayList中的操作不是线程安全的!所以,建议在单线程中才使用ArrayList,而在多线程中可以选择Vector或者CopyOnWriteArrayList。
ArrayList是实现List接口的,底层采用数组实现。
ArrayList 实现了Cloneable接口,即覆盖了函数clone(),能被克隆。
ArrayList 实现java.io.Serializable接口,这意味着ArrayList支持序列化,能通过序列化去传输。
Java新手教程之ArrayList的基本使用_java_脚本之家
关于ArrayList的使用_菜鸟是鸟菜的博客-CSDN博客_arraylist怎么用
ArrayList常用方法总结_涟涟涟涟的博客-CSDN博客_arraylist方法