基础知识
对象和类:
Java中万物皆对象,而类是对一些具有相同属性或者行为的对象的抽象,是一个模板。
创建对象的5种方式:
- 使用new关键字
- 使用Class类的newInstance方法
- 使用Constructor类的newInstance方法
- 使用clone方法
- 使用反序列化
类中含有
成员属性:在类内部,方法体外部,作用于整个类,
成员方法,和成员变量同级
局部变量,在方法体内部,作用于方法体。当成员变量和局部变量重名时,调用的时距离最近的变量。
局部变量就是在类中的方法中定义的变量,在方法中临时保存数据,局部变量存储在内存的栈中,生命周期是随方法的调用而存在,随方法的调用完毕而消失。
成员变量就是在类中定义,用来描述对象将要有什么,成员变量存储在内存的堆中,生命周期是对对象的存在而存在,随对象的消失而消失。
类变量,带有修饰符static的变量,随着属于类,随着类的创建而存在,其实例对象共享一个变量。
构造方法:一般用于初始化对象,当遇到继承的时候要注意关键字this和super,都只能存在于第一行,所以只能有一个!只能被new(实例化对象),不能被调用,
对象则是类的具体的实例,有具体的属性和行为。
基本数据类型:8
Byte(1字节) short(2) int(4) long(8) char(2) boolean float(4) double(8)
类型转换:向上转型(小→大) 向下转型(大→小)
引用数据类型:数组,类,接口,
变量类型:成员变量,局部变量,类变量
访问权限:
Public:所有类可见
Private:同一类内部可见
Protented:对同以包内的类和不同包中的有继承关系的类可见
实例化子类对象,子类不重写protected修饰的变量或方法,可在子类对象中调用父类属性或方法。(其实就是继承了父类,然后自身拥有了和父类相同的属性或方法,然后可以被调用,若此时把父类修饰符改为private,则子类对象中不能调用,就算实例化父类也不行!!!)
Friendly:同一个包内可见。
Synchronized:关于线程安全的时候的同步锁,当临界资源被争抢使用时需要添加,表示用以时间只能被一条线程使用。
Volatile:修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值,而且当成员变量发生变化时,强迫线程将变化值写回到共享内存。
Transient:临时变量
循环结构:do---while while for foreach iterator listiterator
String:
码点:unicode值 代码单元:对应的字符!!!
String:长度不可变
StringBuffer:线程安全,速度慢,支持同步
StringBuilder:线程不安全,速度快,不可同步
关于String,StringBuffer,StringBuilder的区别,
String长度不可变,但是却可以让字符串被共享,只有字符串常量是被共享的,而+或substring等操作产生的结果并不是共享的,所以判断字符串是否相等的话不能用==,要用equals方法,==是判断是否放在了同一个地方。
数组:用来存放同一种类型的容器,由于是同一类型,所以操作时候不需要考虑类型转换问题,效率高!
类的加载:
类的加载指的是将类的.class文件中的二进制数据读入内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象放在堆区中,和方法区中的类就像镜面映射得到的一样。
类的加载是由类加载器完成的,类加载器通常是由JVM来提供的,类加载的过程是父亲委托机制,在这种机制中,先委托父加载器,直到根类加载器,然后再由最初的加载器加载,如果都无法加载则报错ClassNotFound的异常,
然后连接:负责把类的二进制数据合并到jre中,该过程又分为三个阶段:
验证:确保被加载的类的正确性,包括四方面的检查:
- 类文件的检查:确保程序使用的是Java类文件的固定文件
- 语义检查:确保类符合Java语言的语法规定
- 字节码验证:确保字节码可以被jvm安全执行
- 二进制兼容验证:相互调用的类之间的协调一致
准备:jvm为类的静态变量分配内存,并设置默认的初始值,
解析:jvm会把类的二进制数据中的符号引用替换为直接引用
最后是类的初始化:为类的静态变量赋予正确的初始值
所有的jvm的实现,必须在每个类或接口在Java程序“首次主动使用“的才会初始化他们。
主动使用的六种情况:
- 创建类的实例
- 访问某个类或者接口的静态变量,或者对该静态变量赋值
- 调用类的的静态方法
- 反射
- 初始化某个类的子类
- Jvm启动时被标明为启动类的类
自己的理解:当运行Java虚拟机的时候,第一件事就是寻找入口, main方法,test等等,于是加载器开始启动并找出xxx.class文件,,在对它进行加载的过程中,判断是否有基类(有的话继续向上加载...)然后基类中的static被初始化,→导出类的static初始化!然后就执行main方法中的代码!!!
第一部分:面向对象
抽象
对事物进行简化,只提取对问题的解决有帮助的部分。其余的部分全部舍弃。
封装
概念:属性私有化,对外提供公共的get(),set()方法。
举例:创建一个封装类,意思就是该类中是用来提供存放数据的,然后其数据对外是不可修改的(意思是不可以直接通过new对象,然后对象名.属性修改,只能通过提供的公共的set,get方法进行修改,这样的好处就是可以我们可以对类中的属性进行控制,不是任何数据都可以进行存储的。),
继承
子类拥有父类的所有属性和方法,并且还有自己特有的属性和方法。其实现的方式有extends和implements。
所有类的超类都是Object,其中有几个方法需要注意:
Equals():每个类都要有自己equals()方法,当对象内容需要进行比较的时候必须进行重写。
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Equals other = (Equals) obj;
if (address == null) {
if (other.address != null)
return false;
} else if (!address.equals(other.address))
return false;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
hashCode():当重写equlas的时候必须重写hashCode(),因为equals是以hashCode为标准判断是否相等的。
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((address == null) ? 0 : address.hashCode());
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
toString():重写其方法可以直接打印对象名,默认为对象名.toString()
clone():
关键字:extends implements instanceof
继承的设计技巧:
1.将公共操作和域放在超类中
2.不要使用受保护的域(原因1:任何一个人都可以由一个类派生出来一个子类,并编写代码直接访问protected的实例域,从而破坏了封装性!原因2:Java中在同一个包内的所有类都可以访问protected域,而不管它是否为这个类的子类)。
3.使用继承实现“is-a”关系
4.除非所有继承的方法都有意义,否则不要使用继承
5.在覆盖方法时,不要改变预期的行为。
6.使用多态,而非类型信息
7.不要过多的使用反射!反射适用于编写系统程序,通常不适用于编写应用程序。
三大修饰符:
Static:
可修饰方法,变量,代码块,不可以修饰类!
修饰方法时在调用该方法时不需要在实例化所在类,直接类名.方法名调用。随类的加载就被分配内存。可以被继承,没有多态。
修饰变量时该变量代表类变量,该类的所有实例对象都公用一个。
修饰代码块,作用是给类进行初始化!优先于主函数的执行
被static修饰过的就属于类,存在于对象之前!
Static:属于类修饰符,可以把相应的属性或方法变为类级别的,使之伴随类产生和销毁,局部变量不能被修饰为static,静态方法也不能使用非静态变量。
被static 修饰的变量称为静态成员变量或类成员变量。静态成员可以使用类名直接访问,也可以使用对象名访问,推荐直接使用类名访问。
静态成员还是属于成员变量,其生命周期还是随着类的调用而存在,随类的调用结束而消失。
被static修饰的方法成为静态方法,静态方法可以直接调用同类中的静态成员,但是不能直接调用非静态成员,(需要通过创建类的对象,然后通过对象来访问非静态成员),在普通成员方法中可以直接访问同类中的静态成员和非静态成员,静态方法不能直接调用非静态方法,需要通过对象来访问非静态方法。
总结:static 只能修饰变量和方法,不能修饰类!!!
修饰过的方法和变量可以在类中任何地方直接调用,没修饰的只能先实例化在调用。
代码块:静态代码块→初始化类
动态代码块→初始化(所有)对象
构造函数→初始化(特定)对象
Abstract:
可修饰类,方法,修饰方法的时候不需要因为是抽象方法没有方法体,所以就不要写{},直接+;。
修饰类的时候此类不可被实例化,只能被子类实现其抽象方法后通过实例化子类调用其属性方法,
修饰的方法为抽象方法,只有声明没有实现,只能定义在抽象类中。
修饰类:抽象类,含有抽象方法的类一定是抽象类,抽象类中的抽象方法一定要被子类继承,若子类没有继承,则子类也一定为抽象类。可以由构造方法!!
方法:没有具体的方法体,只是一个抽象概念,需要被重写使用,只有声明没有实现。
Final:可修饰类,方法,变量。
修饰类不能被继承,
修饰方法可以被继承,不可以被重写!
修饰变量时表示该变量不可被修改,声明的同时进行初始化!局部变量可以先声明再初始化,但是在使用该变量之前一定要初始化!