【强类型、弱类型】关注的是是否允许隐式类型转换。
【静态类型、动态类型】关注的是检查数据类型的时机。
- 强类型:偏向于不容忍隐式类型转换。譬如说haskell的int就不能变成doubl
- 弱类型:偏向于容忍隐式类型转换。譬如说C语言的int可以变成double
- 静态类型:编译的时候就知道每一个变量的类型,因为类型错误而不能做的事情是语法错误。
- 动态类型:编译的时候不知道每一个变量的类型,因为类型错误而不能做的事情是运行时错误。譬如说你不能对一个数字a写a[10]当数组用。
动态类型:类型对于变量,属性,方法以及方法的返回类型都是可有可无的,在给变量赋值时才决定它的类型.可以把值类型转换成引用类型,引用类型转换成值类型。当需要时,很多类型之间都会发生自动转换
静态类型:语言为了达到多态会采取一些类型鉴别手段,如继承、接口,实现运行时多态性的基础是动态方法调度,它是一种在运行时而不是在编译期调用重载方法的机制。
java是强类型、静态类型语言, 需要大量的语句才能满足类型系统的要求
目录
访问修饰符
8种基本数据类型
数据类型转换
变量
语句相关
函数/方法
内部类
数组
访问修饰符
- public 一个类中,同一包中,子类中,不同包中
- protected 一个类中,同一包中,子类中
- default 一个类中,同一包中
- private 一个类中
(修饰类成员)
- 成员使用private修饰只在本类中使用。
- 如果一个成员没有使用任何修饰符,就是default,该成员可以被包中的其他类访问。
- protected成员被protected修饰可以被包中其他类访问,并且位于不同包中的子类也可以访问。
- public修饰的成员可以被所有类访问。
(修饰类)
- 类只有两种public和默认(成员内部类可以使用private))
- 父类不可以是private和protected,子类无法继承
- public类可以被所有类访问
- 默认类只能被同一个包中的类访问
8种基本数据类型
整型
byte 代表一个字节的大小 8bit 2(8) -128~127 256
short 代表两个字节的大小 16bit 2(16) -2(15)~2(15)-1
int 代表四个字节的大小 32bit 2(32) -2(31)~2(31)-1
long 代表八个字节的大小64bit 2(64) -2(63)~2(63)-1
浮点型
float 代表四个字节的大小 32bit
double 代表八个字节的大小 64bit
字符型
char 代表两个字节的大小 16bit 2(16)
布尔型
boolean 占一个字节或4字节。只有true与false两个值。基本类型占4个、数组类型占1个字节
注意:java中整数默认是int,小数默认是double
数据类型转换
- 自动类型转换(也叫隐式类型转换, 小数据类型———>大数据类型 )
要实现自动类型的转换,需要满足两个条件:1.两种类型彼此兼容,2.目标类型取值范围必须大于源类型 (子类转父类)。
所有的数字类型,包括整形和浮点型彼此都可以进行转换。
- 强制类型转换(也叫显式类型转换, 大数据类型———>小数据类型 )
1.两种类型彼此不兼容,2.目标类型取值范围小于源类型(父类转子类)时,无法自动转换,
此时就需要进行强制类型转换。会造成损失精度!!!
没有继承关系的两个类,互相转换,一定会失败
变量
局部变量:定义在方法/函数内部, 离开该函数后就是无效的,再使用就会报错。
全局变量/成员变量:定义在所有方法外,类内,在整个类中都可以被访问。
初始值 :
成员变量 存储在堆中,如果没有赋初值,它有默认值。
1. 整数byte、short、int、long =0;
2. char='\uoooo';(Unicode字符,null)
3. boolean =flase;
4. String =null;
5. 类类型 =null;
6. 数组 =null;
局部变量,如果要想使用必须手动初始化.
1. 方法中,参数列表中,语句中。
2. 必须给初始化值,没有初始值,不能使用
3. 在栈内存中
语句相关
switch语句选择的类型只有:byte,short,int , char,枚举类型,(String)
而且case后跟的值必须是常量,不能跟变量。在5.0 增加了对枚举的判断。jdk 7.0中对switch 进行了增强可以判断字符串。
运行过程:switch语句一旦匹配上了一个case语句就会执行对应的case中的语句代码,执行完毕之后如果没有遇到break关键字或者是结束switch语句的大括号,那么不会再判断,按照代码的顺序从上往下执行所有的代码。
遇到break关键字或者是结束switch语句的大括号停止。
continue只能用于循环语句中,结束本次循环继续下一次循环
break,continue可配合标记使用,跳转到标记处,类似goto
函数/方法
方法和方法之间不能嵌套,方法之间通过调用来使用。 main方法是程序的入口由虚拟机调用。
函数中只能调用函数,不可以在函数内部定义函数。函数之间是平级的,相互之间是调用的关系。
定义函数时,函数的结果应该返回给调用者,交由调用者处理。
函数什么时候执行完毕:当执行完return语句,或者执行到函数末尾的花括号时方法结束。
函数返回值类型是具体的,那么该函数就必须在任意情况下都保证有返回值。
方法重载:在同一个类中,有一个以上的同名函数,只要函数的参数列表或参数类型不一样即可,与返回值无关, 这些统称为方法的重载。
类
每个编译单元(一个.java文件下)都只有一个 public 类。因为每个编译单元都只能有一个公共接口,用 public 类来表现。但可以有多个类(非内部类),只能有一个类是public,且这个类必须与文件名一致。
只能有一个 public 类是为了给类装载器提供方便。 一个 public 类只能定义在以它的类名为文件名的文件中。
编译不需要main方法,运行才需要,java程序是从一个 public 类的 main 方法开始执行的,(其实是 main 线程)。
内部类
一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。广泛意义上的内部类一般来说包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类。
事实上,编译器在进行编译的时候,会将成员内部类单独编译成一个字节码文件 , 成员内部类中的 this&0 指针便指向了外部类对象因此可以在成员内部类中随意访问外部类的成员
外部类class文件名是:外部类名.class
内部类class文件名: 外部类名$内部类名.class
匿名内部类和局部内部类class文件名:外部类名$n.class n为正整数
局部内部类和匿名内部类只能访问局部final变量,(因为生命周期不一致,可能出现外部类变量生命周期结束,但内部类还在。 所以用final修饰内部类局部变量不可变,内部类访问的局部变量其实是一个复制品)
成员内部类(静态/非静态)
:类内定义类
好处:内部类可以直接访问外部类所有成员
细节:
1.内部类可以直接访问外部类所有成员
2.如果外部类与内部类存在同名成员变量时,在内部类中默认访问内部类的成员变量。可通过 " 外部类.this.成员变量名 " 指定访问外部类的成员
3.私有的成员内部类只能在外部类提供一个方法创建内部类的对象进行访问,不能在其他类创建对象
4.成员内部类一旦出现了静态的成员,那么该类也必须使用static修饰
访问方式:
1.在外部类提供一个方法创建内部类的对象访问
2.在其他类直接创建内部类对象。格式: " 外部类.内部类 变量名 = new 外部类.new 内部类() "
3.如果是静态内部类,在其他类创建格式为: " 外部类.内部类 变量名 = new 外部类.内部类() "
静态内部类是不依赖于外部类的,也就说可以在不创建外部类对象的情况下创建内部类的对象。另外,静态内部类是不持有指向外部类对象的引用
public class 外部类{
//非静态内部类
class 内部类1{
//需要实例化 new 外部类().new 内部类1()
//直接访问外部类的private实例属性name的
}
//静态内部类
static class 内部类2{
//不需要一个外部类的实例为基础,可以直接实例化 new 外部类().内部类2()
//在静态内部类里面不可以访问外部类的实例属性和方法
}
}
局部内部类
:类的方法内部定义另一个类
细节:
如果局部内部类访问了一个局部变量,那么该变量必须使用final修饰。(因为生命周期不一致,所以内部类访问的局部变量其实是一个复制品)
局部内部类就像是方法里面的一个局部变量一样,是不能有 public、protected、private 以及 static 修饰符的。
public class 外部类{
public void 方法(){
class 内部类{
}
}
}
匿名内部类
没有类名的类就成为匿名内部类,一般用于实参
匿名内部类本质上就是在继承其他类,实现其他接口
好处:简化书写
使用前提:必须存在继承或实现关系格式:
new 父类或者父接口(){
匿名内部类成员
在匿名类中使用外部的局部变量,外部的局部变量必须修饰为final
执行代码….
};
细节:使用匿名内部类时,如果需要调用匿名内部类的两个方法或者两个方法以上。可以使用变量指向该对象。
数组
给数组分配空间时,必须指定数组能够存储的元素个数来确定数组大小。创建数组之后不能修改数组的大小。
数组间元素和元素的内存地址连续。
定义: 元素类型[] 数组名 = new 元素类型[元素个数或数组长度];
例:
int []x=new int[3];
注:左半部分=声明数组变量(int x[] 也是一种创建数组的格式。推荐使用int [] x 的形式声明数组),右半部分=创建数组(首先使用new int[3] 创建了一个数组,然后把这个数组的引用赋值给数组变量x。)
可以使用length 属性获取数组的大小:数组名.length
数组工具类(Arrays)
排序: sort() 将数组按照升序排列
遍历: toString() 将数组的元素以字符串的形式返回
查找: binarySearch()在指定数组中查找指定元素,返回元素的索引,如果没有找到返回(-插入点-1) 注意:使用查找的功能的时候,数组一定要先排序。