java的核心思想是面向对象,Java语言的三大特性是:封装、继承、多态(从一定角度来看,封装和继承几乎都是为多态而准备的)
多态的定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式
java中的一些机制
实现多态的机制,事件监听机制,异常处理机制,反射机制,垃圾回收机制,类加载机制
重载Overloading:方法重载是让类以统一的方式处理不同类型数据的一种手段。多个同名函数同时存在,具有不同的参数个数/类型。重载Overloading是一个类中多态性的一种表现。
重写Overriding:父类与子类之间的多态性,对父类的函数进行重新定义。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。在Java中,子类可继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写(覆盖)。子类函数的访问修饰权限不能少于父类的
jvm
两张图,描述编译和执行的过程
Java代码编译是由Java源码编译器来完成,流程图如下所示:
java关键字
51+2个保留字=53个关键字(java的关键字都是小写的!!)
2个保留字,Java语言的的保留字是指预留的关键字
const 常量,用于修改字段或局部变量的声明。它指定字段或局部变量的值是常数,不能被修改
goto 转到,指定跳转到标签,找到标签后,程序将处理从下一行开始的命令
1).访问修饰符的关键字(共3个)
关键字 |
意思 |
备注,常用 |
public |
公有的 |
可跨包,(默认选择) |
protected |
受保护的 |
当前包内可用,同包内类不用import,protected修饰的成员变量和方法在同包内才能用
|
private |
私有的 |
当前类可用 |
2).定义类、接口、抽象类和实现接口、继承类的关键字、实例化对象(共6个)
关键字 |
意思 |
备注,常用 |
class |
类 |
public class A(){} 花括号里有已实现方法体,类名需要与文件名相同 |
interface
|
接口 |
public interface B(){} 花括号里有方法体,但没有实现,方法体句子后面是英文分号“;”结尾.interface前加不加abstract都一样,因为interface本身就是抽象的 |
abstract
|
声明抽象 |
public abstract class C(){} 介于类与接口中间,可以有也可以没有已经实现的方法体 |
implements
|
实现 |
用于类或接口实现接口public class A implements B(){} |
extends
|
继承 |
用于类继承类 public class A extends D(){} |
new |
创建新对象 |
A a=new A(); A表示一个类 |
3).包的关键字(共2个)
关键字 |
意思 |
备注,常用 |
import |
引入包的关键字 |
当使用某个包的一些类时,仅需类名 然后使用ctrl+shift+o或者选定类名(类或属性或方法)按住ctrl+单击 即可自动插入类所在的包。如:JFrame 快捷键之后自动加入 import javax.swing.JFrame; |
package |
定义包的关键字 |
将所有有关的类放在一个包类以便查找修改等。如:package javake.flycat.draw002; |
4).数据类型的关键字(共12个)
关键字 |
意思 |
备注,常用 |
byte |
字节型 |
8bit |
char |
字符型 |
16bit |
boolean |
布尔型 |
-- |
short |
短整型 |
16bit |
int |
整型 |
32bit |
float |
浮点型 |
32bit |
long |
长整型 |
64bit |
double |
双精度 |
64bit |
void |
无返回 |
public void A(){} 其他需要返回的经常与return连用 |
null |
空值 |
|
true |
真 |
|
false |
假 |
|
5).条件循环(流程控制)(共12个)
关键字 |
意思 |
备注,常用 |
if |
如果 |
if(){} 如果小括号里面怎么怎么样 花括号就怎么怎么样 |
else |
否则,或者 |
常与if连用,用法相同 |
while |
当什么的时候 |
while 怎么样就do什么 while(){} |
for |
满足三个条件时 |
for ( ; ; ){} |
switch |
开关 |
switch(表达式) |
case |
返回开关里的结果 |
|
default |
默认 |
|
do |
运行 |
长与while连用 |
break |
跳出循环 |
|
continue |
继续 |
中断本次循环,并并开始下一次 |
return |
返回 |
return 一个返回值类型 |
instanceof |
实例 |
一个二元操作符,和==,>,<是同一类的。测试它左边的对象是否是它右边的类的实例,返回boolean类型的数据 |
6).修饰方法、类、属性和变量(共9个)
关键字 |
意思 |
备注,常用 |
static |
静态的 |
属性和方法都可以用static修饰,直接使用类名.属性和方法名。 只有内部类可以使用static关键字修饰,调用直接使用类名.内部类类名进行调用。 static可以独立存在。静态块 |
final |
最终的不可被改变的 |
方法和类都可以用final来修饰 final修饰的类是不能被继承的 final修饰的方法是不能被子类重写。 常量的定义: final修饰的属性就是常量。 |
super |
调用父类的方法 |
常见public void paint(Graphics g){ super.paint(g); ··· } |
this |
当前类的父类的对象 |
调用当前类中的方法(表示调用这个方法的对象) this.addActionListener(al):等等 |
native |
本地 |
|
strictfp |
严格,精准 |
|
synchronized |
线程,同步 |
|
transient |
短暂 |
|
volatile |
易失 |
|
static 例子:
public class Test{
class A{} //内部类
ActionListener al=new ActionListener(···){} //匿名内部类
}
静态块优先于其他方法/类的执行
7).错误处理(共5个)
关键字 |
意思 |
备注,常用 |
catch |
处理异常 |
1.try+catch (来自网上的资料) 总结:
|
try |
捕获异常 |
|
finally |
有没有异常都执行 |
|
throw |
抛出一个异常对象 |
一些可以导致程序出问题的因素,比如书写错误,逻辑错误或者是api的应用错误等等. 为了防止程序的崩溃就要预先检测这些因素,所以java 使用了异常这个机制. 在java中异常是靠 "抛出" 也就是英语的"throw" 来使用的,意思是如果发现到什么异常的时候就把错误信息 "抛出"
|
throws |
声明一个异常可能被抛出 |
把异常交给他的上级管理,自己不进行异常处理 |
throw是你执行的动作。比如你觉得可能有异常,那么就抱出去 如:
String a; if(a == null),
throw new exception("a为null");
所以throw是一个抛出去的动作
throws只用在一个方法的末端,表示这个方法体内部如果有异常,这抛给它的调用者。 如: public void add(int a, int b) throws Exception(); 这个方法表示,在执行这个方法的时候,可能产生一个异常,如果产生异常了,那么谁调用了这个方法,就抛给谁。(来自百度)
8).不知道是什么(共2个)
关键字 |
意思 |
备注,常用 |
enum |
枚举,列举型别 |
|
assert |
断言 |
|
java泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展
作用:
1,(不用检查)类型安全
2,消除强制类型转换
实现原理:类型擦除,类型擦除是在编译期完成的。Java的泛型是伪泛型。在编译期间,所有的泛型信息都会被擦除掉。
泛型类(实例化类的时候指明类的类型):public class Test<T>{};Test<Object> t = new Test<Object>();
泛型方法(调用的方法持有泛型,可以把泛型看做参数/占位符):public <T>T getObj(Class<T> O){};
泛型接口
java 注解
Java的annotation没有行为,只能有数据。让其实现某些行为必须有实例(代理对象),再用反射技术执行某些行为
java io nio
流:有序字节(byte=8bit)序列集合。作用:使数据在两个设备间传输,因为它输入流提供读入、输出流写出的功能。
字节流:xxxInputStream/OutputStream(InputStream 是所有的输入字节流的父类,抽象类)
ByteArrayInputStream(byte[] buf, int offset, int length) 用byte[]构造流
FileInputStream(File file) 用file构造流,
用read()方法取出FileOutputStream(File file) 用file构造流,将文本内容write()写入到file中
字符流(纯文本数据):xxxReader/Writer ;
BufferedReader(Reader in)构造,readLine()读入
BufferedWriter(Writer out)构造,write()写入
io:面向流,阻塞io,一个线程处理一个连接
java的三种代理模式
代理模式的作用是:为其他对象提供一个代理对象以控制对目标对象的访问。代理对象可以在客户端和目标对象之间起到中介的作用,在目标对象实现的基础上,增强额外的功能操作
编程中的一个思想:不要随意去修改别人已经写好的代码或者方法,如果需改修改,可以通过代理的方式来扩展该方法
静态代理:需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类
动态代理/JDK代理:
1.代理对象,不需要实现接口
2.代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要我们指定创建代理对象/目标对象实现的接口的类型)
3.动态代理也叫做:JDK代理,接口代理
代理类所在包:java.lang.reflect.Proxy
JDK实现代理只需要使用newProxyInstance方法,但是该方法需要接收三个参数,完整的写法是:
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )
注意该方法是在Proxy类中是静态方法,且接收的三个参数依次为:
ClassLoader loader,
:指定当前目标对象使用类加载器,获取加载器的方法是固定的Class<?>[] interfaces,
:目标对象实现的接口的类型,使用泛型方式确认类型InvocationHandler h
:事件处理,执行目标对象的方法时,会触发事件处理器的方法,会把当前执行目标对象的方法作为参数传入
Cglib代理,也叫作子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能的扩展.
- JDK的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口,如果想代理没有实现接口的类,就可以使用Cglib实现.
- Cglib是一个强大的高性能的代码生成包,它可以在运行期扩展java类与实现java接口.它广泛的被许多AOP的框架使用,例如Spring AOP和synaop,为他们提供方法的interception(拦截)
- Cglib包的底层是通过使用一个小而块的字节码处理框架ASM来转换字节码并生成新的类.不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉.
1.需要引入cglib的jar文件,但是Spring的核心包中已经包括了Cglib功能,所以直接引入
pring-core-3.2.5.jar
即可.2.引入功能包后,就可以在内存中动态构建子类
3.代理的类不能为final,否则报错
4.目标对象的方法如果为final/static,那么就不会被拦截,即不会执行目标对象额外的业务方法.
InnoDB:提供了事务、行级锁机制和外键约束的功能
memory(heap):只存在于内存中。使用散列索引,所以数据的存取速度非常快。这种类型常应用于临时表中
archive:这种类型只支持select 和 insert语句,而且不支持索引。常应用于日志记录
1.利用索引在 where 及 order by 涉及的列上建立索引
2.避免使引擎放弃使用索引而进行全表扫描,以下情况会导致放弃索引进行全部扫描
where 子句中使用!=,<>操作符,null 值判断,前置%的like,in, not in, or, 使用参数, 字段进行表达式操作,
3.避免导致索引无法正确使用:
“=”左边进行函数、算术运算或其他表达式运算
4.外表子查询时exists 和 in的选择
5.索引数最好不要超过6个
6.避免更新 clustered 索引数据列
7.尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型
8.使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些
9.表变量和临时表的选择,数据量小用表变量,数据量大用临时表
11.避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写
分表是将一个大表按照一定的规则分解成多张具有独立存储空间的实体表,我们可以称为子表,每个表都对应三个文件,MYD数据文件,.MYI索引文件,.frm表结构文件。app读写的时候根据事先定义好的规则得到对应的子表名
分区和分表相似,都是按照规则分解表。不同在于分表将大表分解为若干个独立的实体表,而分区是将数据分段划分在多个位置存放,可以是同一块磁盘也可以在不同的机器。分区后,表面上还是一张表,但数据散列到多个位置了。app读写的时候操作的还是大表名字
由于多线程导致的内存溢出,在不能减少线程数或者增加系统内存的情况下,只能通过减少最大堆和减少栈容量来换取更多线程
运行时常量池溢出(方法区(算永久代)溢出,调大-XX:MaxPermSize、-XX:PermSize)
堆空间 | -Xms | 启动JVM时的初始堆大小 |
-Xmx | 堆空间最大值 | |
新生代空间 | -XX:NewRatio | 新生代与老年代的比例 |
-XX:NewSize | 新生代大小 | |
-XX:SurvivorRation | Eden区域SurvivorRation区的比例 | |
永久代空间 | -XX:PermSize | 启动JVM时的初始永久代大小 |
-XX:MaxPermSize | 永久代空间最大值 |
比较两个类是否相同
obj.getClass==String.class
比较两个对象是否相同
基本数据类型使用"=="
Java API中,有些类重写了equals()方法,基本数据的封装类
重写equals()方法的步骤一般如下:
1、先用“==”判断是否相等。
2、判断equals()方法的参数是否为null,如果为null,则返回false;因为当前对象不可能为null,如果为null,则不能调用其equals()方法,否则抛java.lang.NullPointerException异常。
3、当参数不为null,则如果两个对象的运行时类(通过getClass()获取)不相等,返回false,否则继续判断。
4、判断类的成员是否对应相等。往下就随意发挥了