基础
1、javac将java源程序编译成class文件,//注意必须加上.java后缀
java程序启动虚拟机执行放在class文件中的字节码 //不需要.class后缀
2、类文件名称要和类名一致,采用骆驼命名法
3、java程序运行class文件,对于有包名的类,java把包名当成文件夹处理."包名+类名"相当于"文件夹目录+类名"来寻找类。
4、最外层的class(外壳类)是加载程序逻辑的容器,程序逻辑定义了程序逻辑的行为
5、三种注释
①// ②/* 内容 */ ③/** 内容 */(可以自动生成文档)
6、System.out.println(内容) 输出并换行
System.out.print(内容) 只输出不换行
基本数据类型
1、4整2浮1char1布尔
int 4字节、short 2字节、long 8字节、byte 1字节
(长整型数据后面有一个后缀L或l)
float 4字节、 double 8字节(大部分应用程序使用的是double,小数默认为double、除非加后缀F或f)
三个特殊的浮点数:正无穷大、负无穷大、NaN(不是数字)
常量Double.POSITIVE_INFINITY、Double.NEGATIVE_INFINITY
Double.NaN
char对应的值需要用单引号,而“ “对应的是单引号
\u0000 -- \uffff 对应转义序列 解析代码之前会做转换
建议逐一声明变量
常量
使用final来声明常量 ,声明之后无法更改, 常量名建议全大写
final double RATIO;
有时希望在类的多个方法中使用,可以用类常量
public static final double RATIO = 1.2;
运算符
1、/ 两个数都是整数 即整数除法,15/2 == 7 否则结果为浮点
2、三元操作符 condition ? expression1 : expression2;
Math工具类
1、输入为double 输出为double
import static java.lang.Math.*; 则无需Math.
2、Math.sqrt() 返回值为double Math类的静态函数
3、Math.pow(x,a) 返回值为x的a次方
4、Math.sin() Math.cos() Math.tan() Math.atan() Math.atan2()
5、Math.exp(x) 指数,e的x次方
6、Math.log(x) x的以2为底的对数
7、Math.log10(x) x的以10为底的对数
8、Math.round(x) 对小数x进行四舍五入
自动类型转换 double-float-long-int
强制类型转换 (int)x (byte)x
字符串
1、String e = ""
2、子串 String的方法 substring(起始,终止)
String s = str.substring(0,3)
3、拼接 + 号连接
当一个字符串与一个非字符串进行拼接时,后者会被转化为字符串
如果把多个字符串放在一起,用一个定界符分割,可以使用静态方法join()
String all = String.join(" / ","S","M","L","XL")
4、字符串不变性,字符串不能被修改,只能改变字符串变量的指向
5、判断相等 str1.equals(str2) 用compareTo也可以
可以使用字符串变量或字符串常量
"Hello".equals(gretting)也是正确的
如果不区分大小写,则可以使用equalsIgnoreCase()
判断字符串是否相等不能使用==
6、字符串的长度 str.length()
7、判断空串 ""
str.length() == 0 或者 str.equals("")
8、Null串
str == null
判断一个字符串既不是null也不是空串
if(str != null && str.length() != 0)
类和对象
构造函数:先在堆中新建对象,然后构造函数为对象进行初始化,返回该对象的引用。如果想在一个含参数多的构造函数调用含参数少的构造函数,则可以使用this(a,b);
类的封装
private default protected public
类的继承
修饰符 class Subclass extends SuperClass
{//定义部分
}
java的子类不能继承父类的构造函数,单继承,只能有一个直接父类
子类重写父类方法,会发生方法覆盖,“两同两小一大”:
两同:方法名相同、形参列表相同
两小:子类返回值类型小于等于父类、子类抛出异常类型小于等于父类
一大:子类的访问权限大于等于父类
必须都是类方法或实例方法
变量只要名字相同则会覆盖,除非父类中的变量是private
super限定:
可以在子类中调用父类中的实例方法或变量,不能出现在static方法中。构造器中使用,则初始化该类从父类中继承的实例变量。新建子类对象,实际上会分配两块内存,一块是子类、一块是父类,先在父类中找。super则直接到父类中找。
通过super调用父类构造器:
同一个类用this,父子类用super,并且必须出现在第一行
创建任何对象,总是在该类继承树的最顶层类的构造器开始执行,然后依次向下,最后执行本类
多态
编译时类型:定义引用变量时的类型
运行时类型:赋值给变量的变量类型
引用变量在编译时,只能调用编译时类型所具有的的方法,但运行时则执行运行时类型的方法。引用类型只能调用声明该变量所用类中的方法。
引用变量的强制类型转换:
可以将一个 编译时类型是父类,运行时类型是子类,的变量强制转换成运行时类型
其他会报错,为了防止报错
可以使用instanceof运算符判断是否可以
if(objPri instanceof String){
String str = (String)objPri;
}
instance强制类型转换之前先做检测:
判断前面的对象是否是后面的类、或子类、实现类的实例
前面是引用类型变量 instanceof 后面是类
返回true 或 false
前面的引用变量的编译时类型要和后面的类相同或具有父子关系
继承关系和组合关系:继承是is-a,组合是has-a
private Animal a;
public Bird(Animal a){
this.a = a;
}
类中包括:成员变量,构造器,方法,初始化块
初始化块
初始化块在创建对象时执行:
{
}
新建对象的执行顺序:先为实例变量分配内存,然后执行初始化块/声明赋予的初始值(按顺序),然后执行构造器里的初始化
static {
}
静态初始化块只对类进行初始化(类变量)
一个类如果之前没有使用过,则先执行类初始化:java.lang.Object的静态类初始化块 -- 最顶层父类的静态初始化块 -- 次顶层的静态初始化块 -- 。。。 -- 本类的静态初始化块
如果类经过了初始化,则执行对象的初始化,从最顶层类的普通初始化块和构造器 直到该类的普通初始化块和构造器
包装类
8个基本类型对应8个包装类
把基本类型数据赋值给包装类,自动装箱;把包装类赋值给基本类型,自动拆箱
Integer it = 3;
int num = it;
Object obj = 4;
Object多态也支持
基本类型变量和字符串之间的转换:
String intStr = "123";
int it1 = Integer.valueOf(intStr);
xxx a = Xxx.valueOf(str);
int it1 = Integer.valueOf(intStr);
int it2 = Integer.valueOf(intStr);
float ft1 = Float.parseFloat(floatStr);
//把基本类型转换为字符串
String str = String.valueOf(基本类型)
String str = 基本类型 + "";
toString
toString是Object类里的实例,所有java类都是Object类的子类,因此java对象可调用toString()
因此java对象也可以和字符串进行连接,p.toString() + ""
equals
Object类提供的方法,如果不重写,则相当于==,重写可以按照一定规则去判断。String已经重写euqals
==比较的是引用类型的地址。
类成员无法访问实例成员
final
final修饰变量(类、方法、变量),final可以修饰成员变量,局部变量,形参,final修饰的变量不可以被改变,一旦获得初始值便不可被重新赋值。final修饰的成员变量必须由程序员显式地指定初始值。
final修饰的类变量必须在静态初始化块或者定义该类变量时赋初始值
final修饰的成员变量必须在普通初始化块或定义时或者构造器中赋初始值
局部变量可以先定义不赋值,后面只能赋值一次
final修饰的引用类型变量不能被重新赋值,但是它指向的对象可以被修改
宏变量 final常量 final int maxn = 999;
java会使用常量池管理曾经使用过的字符串直接量,String a = "java"则会在常量池中缓存"java",如果再次执行String b = "java",则a和b均指向常量池中的"java" a == b 返回TRUE
只要编译可以确定就是字面量。若调用了函数或含有变量则编译时无法确定
final修饰的方法不可以被子类重写
final修饰的类不可以被继承
Integer.valueOf()创建-128~127的对象时会被缓存
抽象类
抽象方法只有方法签名、没有方法实现
使用abstract修饰符来修饰抽象类或抽象方法
抽象类不可实例化,可以包含成员变量和成员方法
定义了抽象方法、继承了一个抽象父类,但没有完全实现父类抽象方法、实现了接口,但没有完全实现接口包含的抽象方法
更加特殊的抽象类--接口
接口定义多个类共同的公共行为规范,所以接口里通常定义一组公用方法
接口可以定义静态常量、方法(抽象方法、类方法、默认方法需加default、私有方法)、内部类、和内部枚举
接口中的静态常量和接口相关,系统会自动为这些成员变量增加static和final两个修饰符,接口没有构造器和初始化块,只能定义时初始化
实现接口方法必须使用public访问修饰符
内部类
1、非静态内部类
可以访问外部类的成员变量,内部类是外部类的成员,成员可以相互访问(静态除外),外部类无法访问内部类的实现细节,非静态内部类不能拥有静态成员
在一个类中定义的另一个类即为内部类
使用static修饰的即为静态内部类,没有static修饰为非静态内部类
内部类可使用private、protected和public修饰
外部类的上一级是包,默认为default,同一个包内的类可以访问,加了public,则可以被项目访问
成员内部类的形式总是为 OuterClass$InnerClass.class
非静态内部类调用方法,先找局部变量,再找成员变量,最后找外部类的成员变量
外部类的实例变量,OutterClass(类名).this.propName(属性名)
内部类的实例变量,this.属性名
内部类的局部变量:属性名
外部类只能看见 内部类,不能看到内部类的实现细节,只有新建对象才可以,新建一个外部类对象,并没有实例化内部类,所有访问内部类的实例变量是错误的
非静态内部类对象存在时,外部类对象也一定存在
2、静态内部类
可以有静态成员和非静态成员,只能访问外部类的静态成员
静态内部类存在时,不一定有外部类对象,他与外部类相关
3、内部类的使用
在外部类以外定义内部类:
OuterClass.InnerClass varName
如果有包名还要增加包名前缀
创建非静态内部类对象:
OuterInstance.new InnerConstructor()
OutClass.InClass var = new OuterClass().new InClass();
static
静态函数无法访问成员函数
成员函数中省略了代表当前对象的this,而静态函数并不包含this,静态函数属于整个类,所以静态函数无法使用内部类
main方法一定要注意,所以一般要在main方法中,新建外部类对象
static关键字的作用就是把类的成员变成类相关
静态内部类是外部类的一个静态成员,外部类的静态方法,也可以调用
外部类无法直接访问静态内部类的普通成员,但是可以根据类名访问类成员
匿名内部类
创建匿名内部类时会立即创建一个该类的实例,匿名类无法重复使用
new 实现接口() 或者 父类构造器(实参列表)
{
//匿名内部类的类体部分
}
必须实现一个接口或者继承一个父类
匿名内部类不能是抽象类,不能定义构造器,因为没有类名,但可以定义初始化块来完成构造器的任务
实现接口创建匿名内部类无构造器,只有隐式无参构造器
但是继承父类创建匿名内部类,将拥有和父类相似的构造器
如果局部变量被匿名内部类访问,那么会自动使用final修饰