常识
常识
1、面向对象编程(OOP)
对象和类为基础,每个对象都是独立的,当需求变动时,只需要更改很少的代码。
有利于代码的重用和程序的后期维护,能够有效的提高开发效率。
类
:是从现实事物中抽象出来的,是面向对象编程的基础单元,是具有相同属性和行为的一组对象的集合:狗
对象
:则是类的具体实现,是客观世界真是存在的事物:金毛、泰迪。。。
三大特征
: 封装、继承、多态
访问控制符
:public、protected、private
类中三大成员
:构造器、Field、方法
注意:
abstract 和 final 不能同时修饰一个Field
构造器隐式返回该类的实例,所以不能用void 修饰
2、静态变量、静态常量、静态方法
可以通过类名直接访问
static修饰的成员属于类本身,而不属于该类的实例,所以不允许使用类的实例去调用static修饰的Field和方法。
静态变量
:一处变化处处变化 static int a = 10;
静态常量
: final static int a = 10;
静态方法
:对使用频繁的方法使用,可以提高程序的开发效率与性能
注意:将访问比较频繁的静态化,不建议滥用,会一直占用资源,造成资源浪费,直到程序结束才会释放
static修饰的成员不能访问非static修饰的成员
3、值传递与引用传递
Java 没有引用传递,只有值传递。
值传递:将实际参数值的副本(复制品)传入方法内,而参数本身不会受到任何影响。
注意:把对象传给方法时,方法接收的是对象的引用地址,而不是对象本身,引用地址内容变化导致对象也变化。
4、接口和抽象类
1、抽象可以提供成员的实现细节,而接口不能。
2、可以随意的在抽象类中添加新成员,而接口不行
3、一个类可以实现多个接口,但只能继承一个抽象类
抽象:is-a 共性的抽象 接口:like-a 行为的抽象
5、获取类的Class对象
法1:Class.forName("路径")
法2:Student.class
法3:stu.getClass()
6、反射
法1:获取类的Class对象,再调用Class对象的newInstance()方法 (前提是对象必须提供无参构造方法)
法2:获取类的Class对象,再调用Class对象的Constructor类的实例,再调用newInstance(Object ...obj)
7、throw 和 throws 区别
throw:抛出一个异常
throws:方法可能抛出异常的声明
8、对象、引用、指针
Person p = new Person();
p只是一个引用变量,被存放在栈内存
中,指向实际的Person对象;而真正的Person对象则存放在堆(Heap)内存
中。
引用变量与C语言里的指针很像,都是存储一个地址值,通过地址指向实际的对象。Java里的引用就是C里的指针,只是Java把这个指针封装起来,避免开发者进行繁琐的指针操作。
对象与引用变量
当一个对象被创建成功后,这个对象将保存在堆内存中,Java程序不允许直接访问堆内存中的对象,只能通过该对象的引用操作该对象。
不管是数组还是对象,当程序访问引用变量的Field方法时,实际上是访问该引用变量所引用的数组、对象的Field或方法。
堆内存里的对象可以有多个引用:
Person p2 = p; 将p的引用地址复制给p2,共用一个堆内存,属于浅复制
注意:若堆内存的对象没有任何变量指向该对象,那么程序将无法再访问该对象,这个对象也就变成了垃圾,Java的垃圾回收机制将回收该对象,释放该对象所占内存区。如果希望通知垃圾回收某对象,只需要切断该对象的所有引用变量和它之间的关系,也就是将引用变量赋值为null.
9、可变参数
// 以可变参数定义:可变形参放在最后,有且只有一个
public static void swap(String a, String ... b){
System.out.println("b的长度" + b.length + "\n b的值" + b[0] + "\n" + b[1]);
}
// 以数组的方式定义
public static void swap(String a, String[] b){
System.out.println("b的长度" + b.length + "\n b的值" + b[0] + "\n" + b[1]);
}
大部分时候,不推荐重载形参长度可变的方法,意义不大,而且容易降低程序的可读性。
10、五种不同的代码块
1、普通代码块
public void test(){
...
}
2、构造代码块
public class CodeDemo02{
public CodeDemo02(){
System.out.println("========这是构造方法=========");
}
}
3、静态代码块
首次访问时,静态代码块会在非静态代码块前执行
静态块优先于主方法的执行,静态块优先于构造方法的执行,而且只执行一次!
public class CodeDemo03{
static{
System.out.println("这是主类中的静态代码块!");
}
}
4、非静态代码块
非静态代码块会在每次类被调用或者被实例化时就会被执行
public class CodeDemo03{
{
System.out.println("这是主类中的静态代码块!");
}
}
5、同步代码块
同步代码块主要出现在多线程中
synchronized (account){
...
}
11、成员变量、局部变量和运行机制
成员变量
当系统加载或创建类的实例时,系统自动为成员变量
分配内存空间,并在分配内存空间后,自动为成员变量指定初始值。
Person p1 = new Person();
Person p2 = new Person();
p1.name = "张三";
p2.name = "孙悟空";
p1.eyeNum = 2;
p2.eyeNum = 3;
创建第一个对象p1
创建第一个对象 赋值后
所有Person实例访问成员变量时都是访问同一块内存区。
当程序需要访问类的成员变量时,尽量使用类作为主调,而不要使用对象作为主调,避免产生歧义,提高程序的可读性。
不足:
1、增大了变量的生存时间,导致更大的内存开销。
2、扩大了变量的作用域,不利于提高程序的内聚性。
局部变量
局部变量
定以后,必须经过显示初始化后才能使用,系统不会为局部变量执行初始化。这意味着定义局部变量后,系统并未为这个变量分配内存空间,直到程序为其赋初始值后,系统才会为其分配内存,并将初始值保存在这块内存中。
局部变量保存在栈内存中,随代码块运行结束而结束,只保存基本类型的值或对象的引用,所以通常占内存区比较小。
12、隐藏与封装
封装
:指将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象的内部信息,而是通过该类提供的方法来实现对内部信息的操作和访问。
优点:隐藏细节、避免不合理访问、数据检查、便于维护
13、构造器
构造器是创建对象的重要途径,每个类必须包含一个活一个以上的构造器。
14、BIO 与 NIO
BIO
:同步阻塞式IO,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。
不足:虽然此时服务器具备了高并发能力,即能够同时处理多个客户端请求了,但是却带来了一个问题,随着开启的线程数目增多,将会消耗过多的内存资源,导致服务器变慢甚至崩溃,NIO可以一定程度解决这个问题。
NIO
:同步非阻塞式IO,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。
各自应用场景
一旦有请求到来(不管是几个同时到还是只有一个到),都会调用对应IO处理函数处理,所以:
(1)NIO
适合处理连接数目特别多,但是连接比较短(轻操作)的场景,Jetty,Mina,ZooKeeper等都是基于java nio实现。
(2)BIO
方式适用于连接数目比较小且固定的场景,这种方式对服务器资源要求比较高,并发局限于应用中。
当系统开始执行构造器的执行体
参考文章:https://www.cnblogs.com/zedosu/p/6666984.html
15、堆、栈、堆栈
栈
的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据可以共 享。
堆
的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要 在运行时动态分配内存,存取速度较慢。·
堆栈
(stack)。位于通用RAM中,但通过它的“堆栈指针”可以从处理器哪里获得支持。堆栈指针若向下移动,则分配新的内存;若向上移动,则释放那些 内存。这是一种快速有效的分配存储方法,仅次于寄存器。