java的语言特点
-
面向对象(贴近人类思维模式,模拟现实世界,解决现实问题)
-
简单性(自动内存管理机制、不易造成内存溢出;简化流程处理、语义清晰)
-
跨平台(操作系统、服务器)
Java运行机制
一次编写,多次执行
-
JDK :开发工具和类库、包含了jre
-
JRE:运行环境,包含了jvm虚拟机
-
JVM:虚拟机,不同操作系统模拟相同的环境 源文件.java通过虚拟机编译为.class文件
环境变量
变量:系统属性; 变量名----变量值
JAVA_HOME---jdk的根目录, E:\jdk\Java\jdk1.8.0_51
path ----jdk安装目录里的bin;可以任意的路径访问命令; %JAVA_HOME%\bin E:\jdk\Java\jdk1.8.0_51\bin classpath: 类路径;----自从jdk1.5版本后可以不用配;
.;%JAVA_HOME%\lib;
JDK目录;JDK的bin目录:存放的是exe文件,可称为执行文件;
标识符命名规则
语法规则: 由数字、字母、下划线、$组成; 不能以数字开头;
约定: 见名知义; 类名:一个或多个单词首字母大写;例:Hello、HelloWord 方法/变量:一个或多个单词,第一个字母小写,其它单词字母大写;例: getName name pass 包名:全小写,用点分隔,反向域名;例:com.qf.test 常量:全部大写并且用_分隔多个单词;例:HELLO_WORLD
变量
声明变量 给变量赋值
初始化变量
-
第一种定义方式:
类型 变量名=值;
-
第二种定义方式: 类型 变量名; 变量名=值;
-
全局变量
定义在类内,方法外
类内所有的方法里都能用
static 类型 变量名;
public class Demo{
static int age;//全局变量
}
第一个java程序
创建源文件
Demo1.java-----文件名
public class Demo1{ ----类名
}
class Demo2{
}
class Demo3{
}
注:在源文件中,只有被public修饰的类必须与文件名相同;
类名是不可重复的;
通过命令编译生成class文件
javac命令:编译生成字节码文件; javac Demo1.java-->执行-->生成 Demo1.class
执行class文件
java命令:执行字节码文件 java Demo1
数据类型(8种)
基本数据类型
整型
默认整型为int
-
byte 1个字节 范围:-128--127
-
short 2个字节
-
int 4个字节
-
long 8个字节
浮点型
默认浮点型为double,在float类型变量赋值时,常量后必须添加f和F
-
float 4个字节
-
double 8个字节
布尔类型
-
boolean 1个字节 真true/假false
字符型
-
char 2个字节 使用单引号定义 '',引号中只能写一个字符(数字、中文、英文、其它符号)
引用数据类型
字符串
数组
对象
类型转换
自动类型转换
目标类型 = 原类型
-
小转大,整数转浮点数,字符转整数
byte b=100;
int c=b; //类型兼容 byte short int long
double f=c;//类型兼容 整型和浮点型
c='a';//类型兼容 97
强制类型转换
目标类型 = (目标类型)原类型
-
大转小,浮点转整数,整数转字符
byte b=100;
int c=b; //类型兼容 byte short int long
double f=c;//类型兼容 整型和浮点型
c='a';//类型兼容 97
b=(byte)c;//
c=(int)f;
char cc=(char)c;
注:将源类型转为目标类型后,如果数值超出目标类型的范围,则会造成数据的不准确存放;
转义字符
在字符串中表达一些特殊符号时,使用转义字符
换行 | \n |
---|---|
制表符 | \t |
双引 | \ " |
单引 | \ ' |
斜线 | \ \ |
运算符
算数运算符
+ 加法/拼接(当+两侧任意一侧出现String字符串时为拼接)
-
*
/
%---求余数
比较运算符
> 大于
< 小于
<= 小于或等于
>= 大于或等于
== 等于
!= 不等于
注:比较结果一定是boolean类型
例:boolean flag=yushu==1;
赋值运算符
= :将符号右边的值赋给左边的变量,例:int x=10; int y=x+100;
逻辑运算符
-
&& 与 两个都真 ,条件为真
-
|| 或 两个有一个为真,条件为真
-
!非 真变假,假变真
三元运算符
-
表达式?结果1:结果2(一真二假)
条件判断语句
语法
if(表达式){
//执行语句1
}else{
//执行语句2
}
//表达式为真执行语句1 为假执行语句2
if(表达式1){
//执行语句1
}else if(表达式2){
//执行语句2
}else if(表达式3){
//执行语句3
}else{
//执行语句4
}
//表达式1为真执行语句1 为假判断表达式2 表达式2为真执行语句2 为假判断表达式3 表达式3为真执行语句3 为假执行语句4
循环语句
break; --终止当前循环;
while(条件){//变量:1 2 3 4 5 6 7 8 9 10
if(条件){//取值为5
break;
}
System.out.println(变量);//结果:1 2 3 4
}countine; --结束本次循环;
while(条件){//变量:1 2 3 4 5 6 7 8 9 10
if(条件){//取值为5
continue;
}
System.out.println(变量);//结果:1 2 3 4 [5跳过本次循环]6 7 8 9 10
}
-
while循环
while(条件表达式){
//循环体
//迭代变量 i+=1
}
//条件表达式成立则一直执行循环体
-
for循坏
for(初始条件1;循环条件2;迭代变量4){
//循环体3
}
1 234 234 234....2不成立
-
加强for循环
for增强循环:每循环一次,将数组中的元素依次赋值为变量;
for(数组类型 变量:数组名){
System.out.println(变量);
}
-
do{}while循环
先无条件执行,再进行条件判断
do{
//循环体
}while(条件表达式);
-
switch开关分支语句
等值条件:变量与取值之间等于的关系;
变量的类型:byte short int char String,枚举类型
switch(变量){
case 值1:
语句1;
break;
case 值2:
语句2;
break;
case 值3
...
break;
default: //默认以上皆不满足时,执行的语句部分;
....
break;
}
语法:当变量取值1时,执行语句1;如果变量取值2时,执行语句2;
方法
函数也叫方法;用于实现一个功能;
注:同一类内方法不能同名,除非重载;
参数: 形参:定义方法时的形式参数,只有类型 实参:调用方法时的值,只有值 调用方法时,将实参的值依次赋给形参; 返回值: 将调用方法的结果通知调用者; 定义方法时,返回值类型与return后的值一致; 定义方法时,如果方法没有返回值,也可以在方法内使用空return 结束方法;
-
主方法:main
public static void main(String[] args){
//语句
}
-
方法的定义
public static void 方法名(){
//功能
}
注:
参数列表:类型、个数、顺序
返回值:return 值;return是方法的最后一句话;如果一个方法有多个出口,都必须有return语句;
-
方法调用
-
直接调用:
方法名() -
方法类型
-
有参数,有返回值;
-
有参数,无返回值;
-
无参,无返回值;
-
无参,有返回值
-
-
方法重载
在同一类内,方法同名,参数列表不同;
注:参数列表体现:参数个数、参数的顺序、参数的类型; 在类内出现相类似功能,但是参数不同,建议使用相同方法名定义;
-
可变长参数
可变长参数: 类型固定,但是个数不确定,个数表示0个或任意多个: 在参数列表中只能出现一个; 必须出现在参数列表的最后; 被当作数组使用;
public static void test(int... x){ //x就是可变长参数
//x当作数组使用
for(int y:x){
System.out.println(y);
}
}
public static void test2(String... x){
}
//调用:
test()
test(10)
test(20,30)
....任意个参数
-
构造方法(构造器)
特征:
每个类都有一个默认的无参构造器,用于创建对象;
方法必须与类名相同,
构造器没有返回值 没有void
作用:
为了创建对象
单元测试
在方法声明前:添加注解@Test
alt+enter:添加测试环境;add junit4 to classpath;
单独运行测试方法:有@Test注解的方法就可以以run as junit运行
注:测试类建议不要使用Test作类名;
数组
一维数组
存储多个相同的数据类型;有固定长度;
属性:length
-
定义:数据类型[ ] 数组名 = new 数据类型[长度]
int[] arr = new int[n];
int[] arr = {1,2,3}
int[] arr = new int[]{1,2,3,4};
-
访问 读/写
数组名[下标];
arr[n]
数组名.length //数组长度
-
遍历:访问数组中所有元素
-
for
-
for each
-
-
数组的排序
-
冒泡排序
方式:
从第一位开始,相邻两位相比较,如果条件满足,执行两位置上的数相交换;依次,再将二三位的数相比较;
每比较一次,在数组中最后位置处获得最值;
int a[]
int temp = 0;
for(int j = a.length-1; j >=1;j++ ){
for(int i = 0;i<j;i++){
if(a[i]<a[i+1]){
temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}
}
}-
选择排序
方式:
选择第一位与后续其它位相比较,如果条件满足,执行交换;依次再将第二位与其它位相比较,再将第三位与其它位相比较。。。。直到最后两个数比较完成
代码:从大小到/数组 int[] a
for(int i=0;ifor(int j=i+1;j if(a[i] //两数交换
}
}
} -
-
数组扩容
数组的定义要求固定长度和统一类型;
int[] arr=new int[10];---原数组
需求:向原数组增加一个新元素;
问题:覆盖原数组的内容/下标越界;
解决方式:扩容
扩容原理:
创建新数组;
将原数组的内容依次赋值给新数组;
再将新数组返回;return
二维数组
数组中的元素又是一维数组
-
定义
int arr[][] = new int[行][列]
int arr[][] = {{0,0,0,},{0,0,0,},{0,0,0,}}
-
访问:读/写
//赋值
数组名[行下标][列下标]=值;
//取值
数组名[行下标][列下标];
-
遍历
数组名:brr
int[][] brr={
{1,2,3}, ---brr[0]
{4,5,6},
{7,8,9},
{10,11,12}
}
//for
for(int i = 0;i<arr.length;i++){
for(int j = 0;j<arr[i].length;j++){
System.out.print(a[i][j]);
}
System.out.println();
}
//加强for
for(int[] arr:brr){
for(int a:arr){
System.out.print(a);
}
System.out.println();
}
综合案列
登录;注册; 取款;存款;转账;修改密码;
[]数组; String[]user={"zhangsan"} String[]pass={"666"} String[]tel={"11111111"} int[]money={1000} 登录:用户名/密码 进行输入;比较;将输入的信息与存储的信息相比较 取款:输入取款金额;判断余额是否足够; 存款:放钞票;余额变化; 转账:另一个账户存在;余额判断;一方转出/另一方转入; 修改:输入原密码;验证正确;再次输入新密码,再次确认输入;密码保存;
字符串
-
比较
用equals方法:
String str = "aaa"
String str1 = "bbb"
str.equals(str1)
-
int 与 String之间转换
字符串转int,只包含数字字符串"123456"
/字符串转换整型:
int num = Integer.Valueof("123456");//字符串"123456" 转为int类型的 123456
//整型转换字符串转换:
int num = 3;
String str = num+"";
面向对象
类
抽取公共部分的行为、特征定义为一个类.
class Car{
//全局变量:属性====特征
//颜色/品牌/排量
//方法:普通方法====行为
//行驶/倒车/撞车
}
属性(fileld,字段,全局变量,属性,实例成员属性)
特点:
定义在类内、方法外;
在类内处处可用
有默认值
重名:
局部变量可与属性重名,此时局部变量优先级高
public class 类名{
int age;//属性
public void fangFa(){
}
}
随机类(Random)
Scanner---import java.util.Scanner;导包
Random--import java.util.Random导包
注:使用本包以外的其它先引入环境/导包/直接使用; 导入一个包里的多个类时,可以使用 * 通配;
//创建对象
Random rd = new Random();
//产生一个随机数
rm.nextInt(范围) [0~范围)左闭右开
rm.nextInt(9) 产生0~9的随机整数
匿名内部类
相当于子类或实现类;多态使用场景;
抽象类 引用变理=new 抽象类(){
//抽象类的子类
//必须重写抽象方法
};
普通类 引用变量=new 普通类(){
//普通类的子类
//选择性重写方法
};
对象
创建对象,也叫实例化对象;
创建对象四步:
1.堆内存开辟空间
2.初始化对象属性
3.实现构造器代码块内容
4.赋值给引用变量
Car car = new Car();//堆内存中开辟新空间,新空间地址存入到引用变量;
引用变量的类型与对象要兼容
This关键字
调用本类内容
-
调用属性和方法
this.属性名
this.方法名
-
调用本类其他构造方法
调用本类构造时,必须定义在构造方法中的第一句话
this调用构造方法的语句只能出现一次
this()---调用无参构造
this(参数列表)--调用有参构造,按参数的类型、个数、顺序匹配对应的有参构造;
super关键字
super代表父类
调用父类属性、方法(非私有的)
super.属性
super.方法
-
调用父类的构造
super(参数):父类的构造
子类构造器中第一句默认super();
如果没有无参构造需要调用父类其他构造;
this()super()不能同时出现
super()的调用和super(参数)也不能同时出现;
封装
将复杂的实现过程封装在方法里,对外提供简单的调用
-
get/set
-
sexXXXX()通过方法传入数据(设置字段)
-
继承
父类:抽取子类共有的行为特征;
子类:可以调用父类的行为和特征,同时定义自己独有的行为和特征
//子类继承父类非私有成员
class 子类 extends 父类{
}
方法重写
子类重写父类的方法:
@Override用于检查重写的语法
方法名/参数列表(参数个数、顺序、类型都相同)/返回值类型形同;
访问修饰符大于等于父类方法;
抛出异常小于等于父类方法
访问修饰符
private:仅限本类内访问
private 可以修改属性、方法、构造方法;
public:在任何地方都可以访问
public:可以修改类、方法、属性、构造方法
default:默认,当前类内、同一包
可以修饰类、属性、方法、构造方法
protected:当前类内、同一包、跨包后的子类中
用于修饰类、属性、方法、构造方法
多态
一种事务,多种不同形态:父类的引用指向子类的对象
子类和父类之间可以表现出多态;
任何一个子类都可以自动类型提升,提升为父类类型(宽泛的类型),可以将这个父类类型作为返回值/参数定义;达到统一编码,降低耦合度,减少冗余代码
场景一:将多态应用于返回值
class F3{}
class SF3 extends F3{}
class SF4 extends F3{}
class SF5 extends F3{}
class Factory{
public static 父类F3 getF3(int key){
//根据判断结果,返回不同的子类对象
if(key==1)
return new SF3();
else if(key==2)
.....
}
}
场景二:将多态应用于参数
class T{
public void test(){
Mster master=new Master();
Dog dog=new Dog();
master.feed(dog);
Cat cat=new Cat();
master.feed(cat);
master.feed(new Bird());
//以上参数中将子类对象自动向上类型提升,为父类Aniaml类型;
}
}
class Master{
/*public void feed(父类类型 参数){ //在方法调用时给参数传入具体的子类类型;
参数.eat();
}*/
public void feed(Animal obj){
//dog.eat();
obj.eat();
}
}
class Animal{
public void eat(){
System.out.println("eat....");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("dog eat....");
}
}
class Cat extends Animal{
public void eat(){
System.out.println("cat eat....");
}
}
class Fish extends Animal{}
class Bird extends Animal{}
properties文件
在src下创建file-->后缀 properties的文件;
手动添加键值对:英文 键值=值
写程序:
// 创建对象:
Properties p=new Properties();
//加载文件:读文件的内容
p.load(当前类名.class.getClassLoader().getResourcesAsStream("properties文件名"));
// 根据键值获得值:
String 值=p.getProperty(键值)
向上转型(自动)
-
父类类型 引用变量 = 子类对象
向下转型(强制)
子类类型 引用变量 = (子类类型)父类对象
-
instanceof 用于判断父类类型中的真实类型与目标类型是否一致,可以防止运行时异常---类型转换异常
-
父类引用 instanceof 目标类型
-
Object obj=true;
if(obj instanceof String){//判断obj是否为String类型
String ss=(String)obj;
}
装箱
简单类型--》包装类;自动;
Integer num = 10;
拆箱
包装类--》简单类型;自动
Integer num = 10;
int a = num;
abstract关键字
抽象可以修饰类、方法
抽象类:被abstract修饰的类,不可被创建对象,类内可以包含抽象方法、普通方法
public abstract class 类名{
//属性、方法、构造方法(为子类而生)
//但是不能创建对象
//可能含有抽象方法
}
public class 子类 extends 抽象类{ //必须重写抽象父类的所有抽象方法
}
抽象方法:被abstract修饰的方法,没有方法体;只保留方法的声明,必须定义在抽象类内。
访问修饰符 abstract 返回类型 方法名(参数列表)异常 ;
static关键字(静态)
修饰属性、方法、代码块
-
静态属性
属于类的属性,类的所有实例对象都共享一个属性,
可以使用类名直接访问,也支持对象访问
-
静态方法
属于类;类的所有实例对象都共享一个方法;
可以使用类名直接访问,也支持对象访问
定义工具类里方法建议用static
静态方法里不能使用this和super,this和super代表对象,都需要先创建对象,而static与对象创建无关,有可能在对象创建之前就调用静态成员。
静态方法支持重载
静态方法可被继承
不支持重写和多态---多态情况下,不能访问子类独有的方法;
类加载
将类的信息读入到内存中保存
-
当前类创建对象
-
当前子类创建对象
-
-
Class.forName("全类名")
静态代码块
执行:
在类被加载时,优先创建对象和动态代码块之前,执行一次。
静态代码块里只能使用静态代码块
类内可以定义多个静态代码块,定义序即执行序;
static{
}
动态代码块
执行:
每创建一次对象,就优先于构造器执行一次
类内可以定义多个动态代码块,定义序即执行序;
动态代码块内可以使用静态属性和非静态属性;
{
}
final关键字
-
final表示不可改变的。
-
final修饰属性时,这个属性称为常量;一般建议全大写字母表示,多个单词之间下划线连接,在定义时必须初始化
接口
特殊的抽象类,用interface修饰,没有构造器,不能创建对象,静态常量属性;
声明接口:
public interface 接口名{
//属性:公开静态常量属性,默认含有public final static
public static final int AGE=20;
String name="test";
//方法:公开抽象方法,默认含有public abstract
public abstract void login(String name);
}
实现类:接口与类之间的关系用implements表示;也叫多实现;
public class 实现类 implements 接口1,接口2,接口3{
//当前类必须实现(重写)接口中所有抽象方法
}
泛型
用来定义一个类型的代号,并不是真正的
public interface Compare{ //其中T表示泛型代号,并不是有一个类叫“T"
T test();
}
分包使用
实体类:com.qf.pojo,主要用于封装数据
数据访问层: com.qf.dao---Data Access Object数据访问对象,定义接口 com.qf.dao.impl--dao的实现包,定义接口对应的实现 注:一个接口可以有多个实现类; 定义一个标准,由不同的需要确定不同的实现类;
测试类: