开发工具包
*JRE(运行一班的程序)
java运行时的环境 帮助加载外部环境让程序更好运行
*JVM
java虚拟机 实现与平台的无关性
.class文件是字节码文件由我们的javac把我们的代码编译成的 然后 给虚拟机运行
进制相关的问题:
多个进制选用是为了使内存充分利用
BIGdecimal 可实现很大的小数 如宇宙中的灰尘
Biginteger 可实现精度很大的正数
1字节等于8位
Boolean为1位
byte 1字节 -128到127 2的8次方个数
short char 2字节
int(integer) float 4字节
long double 8字节
char范围 0-65535
int 范围 正负21亿
八进制 要求以0开头 如015 byte a = 010 则a值为8
十六进制 要求0x开头 如0x5
转化为二进制字符串 integer.toBinaryString(a);
转化为八进制字符串 integer.toOctalString(a);
转化为十六进制字符串 integer.toHexString(a);
long a = 200; 常量默认为整形 此意思是将整形 转化为long类型
long a2 = 123456123456123L ; 如果后面没有加L还是整形会超出精度 所以要加L
强制转化类型。
double d=3.14 ;常量数默认为 double型
float d = 3.14f ; 因为float4精度 8精度转化为4进度会丢失精度
所以要先强制转化为4精度float
浮点数存在误差
比如 float f=0.1f
double d = 1/10;
此时d!=f 所以最好避免比较中使用浮点数
char类型字符运算先转化为ASCII值运算
比如 char c4 ='a';
int i = c4 + 2;
i值为99
如果把int(4字节)类型转化为char(2字节)型要强制转型
char c5 = (char)i;
强制转化如果超出精度就会随机给个完全不同的值,无意义的值
二元运算会使得类型提升
int a = 3;
int b = 4;
double d = 5.3;
则 int c = (int)(a+b);
float e = (float)(a+d);
有些情况需要我们强制转型
int money = 100000000 //10亿
int years = 20
long total = (long)money*years //因为 int 范围为正负21亿 没有转化时内部
就已经运算超出int范围 ,所以先进行类型提升
long time = 70L*60*24*365*70 //在运算之前我们就要进行精度提升
jdk7.0以上 可以直接显示出二进制的形式 而且switch里面表达结果可是字符串
比如 int是4个字节 共32位
int a = 0b0000_0000_0000_0000_0000_0000_0000_0011(0b加30个0和2个1)
a的值为3
java是强类型语言需要制定类型 js是弱类型
final 定义常量
final double PI = 3.14
当没有达到if语句时此循环将无线执行。
while(true)
{
if(***)
{
break;
}
}
变量用小驼峰 类名用大驼峰 常量用大字母和下划线
逻辑运算用的是短路的方式
<<:左移运算符 相当于乘2
>>:右移运算符 相当于除2取商
如:(移位算法)
3<<1 左移一次等于3*2
12>>2 右移两次 12/2/2
扩展运算符
a+=5等于a=a+5
如果有字符串 出现+ 表示字符串相连
三目运算符(条件运算符)()?a;b
如果()成立就a否则b
int a=3;
int b=5;
String str= "";
str = (a<b)?"a<b";"a>=b";
debug是调试模式
自行双击增加断点
把代码中字符全部替换 ctrl+f
如果判断中很多条件效果相同可以利用case的穿透作用。
break终止整个循环; continue中止当前循环进入下次循环;
带标签的break和continue
首先 要加标签 比如 a:.......
cuntinue a;
Math.round() 四舍五入
math.random() 随机去0到1精度为double的数
递归详解(recursion)
自己调用自己
结构:定义递归头+递归体
定义递归头:什么时候不调用自己(如果没有就死循环)
递归体:什么时候调用自身方法
int recursion(a)//阶乘
{
if(a==1)//递归头
{ return1; }
else //递归体
{ a*a(n-1) }
}
缺点:耗时耗空间
api文档
帮助文档 6.0中文版 7.0英文版
为什么需要包(package)?
-为了方便管理类:适合的类位于适合的包
-为了解决重名的问题
package怎么用
-包名:域名倒着写,再加上模块名,并与内部管理类 类似于com.hpe.text com.hpe.util
生成自己项目的api文档
*使用JAVADOC生成API文档
路径为javadoc.exe
当生成代码格式有问题时在 VM options下面方框内写上 -encoding UTF-8 -charset UTF-8
*特殊注释 :
-文档注释: /**
*常用的java注释标签:
-@Author 作者
-@version 版本
-@param 参数
-@return 返回值的含义
-@throw 跑出异常描述
-@deprecated 废弃。建议用户不再使用该方法
面向对象
1、类 2、对象 3、面对对象编程三大基本特征
组织代码,封装对象 。
面向过程(c语言)线性思维 解决简单的问题
通过方法来组织 ****要素(方法外部定义全局变量,下面写方法)
缺点:写出方法数量有限 变量多的话方法会很繁琐,不容易与别人交流,可维护性低。
(上世纪八十年代软件危机)
优点: 结构体调用 把相关的方法运用结构体丢到一起 管理变量非常方便
贝尔实验室发明的C语言
c++(带类的C )融入了更多的对象
面向对象:把相应的方法丢到一个类,以类为一个单位
优点:以类的方式组织代码 以对象的方式组织(封装数据***
1、方便管理。2、更容易扩展
其他:面向对象适用于非常复杂的程序对象少 简单的程序没必要封装类 用方法就行
对象:是具体的事物
类:是对对象的抽象 (抽象 抽出象(像)的部分) 把对象有相似的部分设计出来
比如:
天使{
带翅膀//这就是抽象的过程
女孩
善良
}
类内属性没赋值 系统会默认给他们值 八种基本数据类型之外默认为null
int 默认为0 float为0.0 boolean:fals char:\u0000
而方法内的变量不会自动赋值。
java种只有值传递。
内存分析
*栈(自动分配连续的空间,后进先出)
放置局部变量
*堆(不连续)
放置new出的对象(对象是以类为模板)
*方法区(也是堆)
1、存放类的信息(代码,属性和方法),2、static变量,3、常量池(字符串常量)等。
常量池可以和其他的类共享
所有引用都是四个字节
***内存内存放的数据在堆内已存在就存放地址来引用。
形参内的值会在方法区开辟一个占帧。
一个类里面涉及到引用的话就优点指针的意思了。根据应用的地址找到源头
当源头的值改变时本身也就改变了
java的回收机制是有计算机来控制的(回不回收人无法控制) system.gc()
c++回收机机制是自己来定义的 (回收可认为控制)
没有人引用的就是垃圾。
构造器:用来构造类的对象,经常也用来初始化对象的属性
1、通过new来调用
2、如果我们没有定义构造器,则系统会自动定义一个无参的构造函数(类似于c++里面的默认构造函数)
3、构造器的方法名必须和类名一致。
格式:
【修饰符】 类名(形参列表){
//n条语句
}
重载(over load)
指的是一个类中可以定义有相同的名字,但参数不同的多个方法,调用时会根据不同的参数表选择对应的方法。
两同三不同
- 同一个类名 - 同一个方法名
- 不同:参数列表不同(类型,个数,顺序不同)
构造器也可以以使用重载
重点是:构造时不产生歧义。
static关键字
在类中 static声明的成员变量为静态变量,或者叫做“类属性,类变量”
*在类被载入时就显示初始化
*static成员变量只有一份,被该类的所有对象共享
*可以使用“对象.类属性”不过一般都是“类名.类属性”
*static变量置于方法区中!
用static声明的方法为静态方法
*不需要对象,就可以调用(类名.方法名)
*在该调用方法时,不会将对象的引用传递给他,所以在static方法中不可访问非static的成员
总结: 类只能使用类的,对象可以使用对象,也可以使用类的。
this 隐式参数
*普通方法中,this总是指向调用该方法的对象
*构造方法中, this总是指向正要初始化的对象
*this不能用于static方法(因为静态static方法中不能访问非static的成员)
this();通过this调用其他构造方法//很多人不知道
面向对象三大特征:
*继承
*封装/隐藏
*多态
继承(extends)
class Mammal extends animal
{
}
子类继承父类可以得到父类的全部属性和方法(除了父类的构造方法)
JAVA中的类只有单继承,没有向c++那样的多继承
多继承,就是为了实现代码的复用性,却引入了复杂性(比如公务员要听科长 局长这些,单继承就直接听上级的就行了)
java中的多继承在接口里可实现
java.lang.object.
继承的最上端口为object 是所有类的祖宗。
ctrl + T 可以看该类的层次继承结构(hierarchy)
super是直接父类对象的引用,可以通过super来访问。
所有的构造器中读一句话就是super(),没有写的系统默认写上(object除外)
所以内存上是该类及父类,父类的父类直到object类都会在内存中(用包裹的方法)创建
super指的是直接父类对象,this指向当前对象 他们都是隐式参数。
就复用的就读来看组合比继承更灵活 但是从建模来栏继承和复用有区别。
“is-a”关系用继承
“has-a”关系使用组合
final关键字:
*修饰变量
- 常量
final int MAX_VALUE = 200;
此时为常量后续 MAX_VALUE不能被修改
*修饰方法:
- 该方法不能被覆盖和重写。
public final void run(){}
*修饰类:
- 修饰的 类不能有子类,不能被继承。 比如 math string
隐藏/封装(encapsulation)
我们程序设计要追求“高内聚,低耦合”
隐藏对象内部的复杂性,只对外公开简单的接口,便于外界调用,从而提高系统的可扩展性,可维护性
类的继承性 由低到高 private default protect public
运用范围 本类可用 同包可用 可不同包但是其子类 都可用
封装要点:
*类的属性处理:
1,一般使用private(除常量和static 应为其在方法区 可共用)
2、提供相应的get/set方法来访问相关属性,从而提供对属性的读取操作
(注意:Boolean变量的get方法是用:is开头 set不变)
*一些只用于本类的辅助性方法可以用private 希望其他类调用的方法用public
多态(polymorphism)
穿的是animal 但是实际上是什么就是什么
Animal a = new cat();
a 引用cat地址
java中如何是实现多态?使用多态的好处?
.应用变量的两种类型
*编译时类型(模糊一点,一般是个父类)
.由声明时的类型决定
*运行时类型(运行时,具体是哪个子类就是哪个子类 )
.由实际对应的对象类型决定
多态存在的3个必要条件:
。要有继承,要有方法重写,父类应用指向子类对象
instanceof
判断是不是某个的对象
if( c instance of cat)
意思是判断 c是否为cat的对象
向下转型实现
Animal a = new cat();//向上转型
Animal b = new pig();
Animal c = new dog();
cat e = (cat) a;//向下转型
比如这里 animal类 a 要是要向下转型实现 上面 对象a 引用的堆内地址就是cat类
抽象类(abstract)
为什么需要抽象类?如何定义抽象类?
. 是一种模板模式,抽象类为所有子类提供了一个通用模板,子类可以再这个模板基础上进行拓展。
. 通过抽象类,可以避免子类设计的随意性。通过抽象类,我们就可以做到严格限制子类的设计,使子类见更加通用。
要点:
. 有抽象方法的类只能定义抽象类
. 抽象类不能实例化,及不能用new来实例化抽象类
. 抽象类可以包含属性、方法、构造方法。但是构造方法不能用new实例。只能用来被子类调用。
. 抽象类只能用来继承
. 抽象方法必须被子类实现。
. 实行设计与实现分离
接口(interface)
比抽象类更抽象的东西
public interface MyInterface
{
//接口中只有:常量,抽象方法
/*public stativ final 接口常量定义时,写或者不写都是这样*/
/*public abstract*/ String MAX_FREAD = "boss";
int MAX_SPEED = 120 ;
public void test01();
public int test02(int a ,int b);
}
规范了设计与实现的分离
实现接口:
public class MyClass implement MyInterface
{
public void test01(){
}
public int test02()
}
.一个类可以实现多个接口
.如子弹和导弹可实现飞 和攻击的两个接口
.接口支持多继承
回调的实现
* CallBack
甩锅 方法给别人写 别人写的什么就是什么
传不同重写对象 实现不同的方法
* hook
//引用类型可以作为形式参数
public void print(Student s )
{
s.show
}
匿名对象 :
是没有名字的对象;
如 new student();
应用场景 :
A:当对象方法仅进行一次调用时
B:匿名对象可以作为实际参事进行传递
因为在内存中没有东西引用 所以使用之后就是垃圾。
内部类(innerclasses)
一般情况, 我们把类定义成独立的单元。有些情况下,我们把一个类放在另一个类
的内部,称为内部类。
内部类的作用:
举例: 外部类是电脑 内部类是cpu 该CPU属于这个电脑
1, 内部类提供了更好的封装,只能让外部类直接访问
不允许同一个包中的其他类直接访问。
2,内部类可以直接访问外部类的私有属性,内部类被当成其外部类的成员。但外部类不能访问内部类的
属性
内部类使用场合:
由于内部类提供了更好的封装特性,并且可以很方便的访问外部类的属性。
所以,通常内部类在职位所在外部类提供服务的情况下优先使用。
创建数组
基本语法
//声明
int[] a;
int b[];
//创建数组对象
a = new int[4];
b = new int[5];
car cars[] = new car[2]
//默认初始化:数组元素相当于对象的成员变量
//动态初始化:
a[0]=23;
a[1]=45;
手动一条一条写,一般用循环
//静态初始化
int c[]={23,45,56,78}
car[] cars={new car("奔驰"),new car("奔驰")}
string
String gh = "a";//a作为String的一个对象;
gh =gh+ 0;
System.out.println(gh);
String str4 = new String("a");//两个对象,a是一个对象,new string出了一个对象
String 和 StringBulder,StringBuffer区别
String 是不可变字符序列 方法内字符存储,字符长度 前面加了private 不能暴露,加了final 方法不能改
stringBuilder是线程不安全的可变字符序列
stringBuffer是线程安全的可变字符序列
StringBuilder sb = new StringBulider(); //初始化 sb是字符长度为16
StringBuilder sb = new StringBulider("sdad"); // 初始化,把adab丢进StringBuilder里
sb.delete(2,3)//删除容器里位置为【2,3)的元素,包头不包尾
.append(str)累加
StringBulder,StringBuffer区别
StringBuffer 比StringBuilder多了 对象锁 synchronized
异常处理机制
两个坏处:
*逻辑代码和错误信息处理(做出判断)放在一起!
*程序本身需要考虑的例外情况比较复杂,对程序员本身要求比较高!
异常的概念
Java是采用面向对象的方式来处理异常的。处理过程为:
*抛出异常:当执行一个方法出现异常,他会生成一个相应的异常对象,停止执行并把异常交给JRE.
*捕获异常:JRE得到该异常后,寻找相应的代码来处理。
类Error
不需要程序员处理,唯一的办法就是重启
类Exception
需要有程序员来处理
类Runtime Exception
一类特殊的异常。如被0整除,数组下标超出范围,如果显示的生命或捕获将会对程序可读性和运行效率影响很大
因此由系统自动检测并将它们交给缺省的异常处理程序(用户可不必对其处理)
类Checked Exception
这一类异常。我们必须驳货进行处理,如用try{}catch{}finally{}
try运行时遇到异常执行catch中的语句,如果try没错误则跳出catch语句,不论出没出错都要运行finally中的语句
多线程
进程和线程的区别
(根本):进程作为资源分配的单位,线程作为调度和执行的单位
(开销):每个进程都拥有独立的代码和数据空间(京城上下文),进程间的切换回有较大的开销。
线程可看作是轻量级的线程,同一类线程共次昂代码和数据空间,每个线程具有独立的运行栈和pc,线程切换的开销小
gc 异常 main 这是一天简单程序的最基本三条线程
第一种方式实现多线程
/**
* 模拟龟兔赛跑
* 1、创建多线程 继承 Thread + 重写run(线程体)
* 2、使用线程:创建子类对象+ 对象。star
* @author TJ
*
*/
静态代理,第二种方式实现多线程(Runnable)
/**
* 静态代理 设计模式
* 1、真实角色
* 2、代理角色: 持有真是角色的引用
* 3、二者实现相同的接口
* @author TJ
*
*/