1、jdk环境配置:
安装jdk后,配置环境变量:
路径:C:\Program Files (x86)\Java\jdk1.6.0_43\bin
环境变量:
计算机右键->属性->高级系统设置->高级->环境变量->系统环境
(1) 新建:变量名:JAVA_HOME
变量值:C:\Program Files (x86)\Java\jdk1.6.0_43
(2)配置path:
在path变量值的最前面添加路径,然后加分号结束
测试:
在cmd中输入java和javac命令
2、运行java文件:
<1>定义java文件(.java)
代码结构:
public class 文件名{
//程序入口
public static void main(String[] agrs){
//输出语句:
System.out.println("输出内容");
}
}
注:<1>java严格区分大小写
<2>运行java文件:
javac 文件名.java //编译java文件
java 文件名 //运行java文件
注:
<1>输出语句中的ln表示换行,也可以在输出语句中添加\n进行换行
示例:
System.out.println("张三\n李四");
<2>如果输出哪些信息,则将该信息放到双引号中原样输出
3、java跨平台原理:
定义完java文件后,有java编译器编译成字节码文件(class文件),
然后由java翻译器翻译成电脑可以识别的二进制代码,所以,java文件的
运行是不直接运行到实体电脑上,所以如果需要运行java文件,则
先安装好jdk(java运行环境)即可运行java文件。
4、开发工具创建java文件:
new->java project->在src下创建package->在package下创建class(Java文件)
注:可以创建多个项目,多个包,多个文件
src---源文件夹--存放java代码
5、改文字大小:
window->preferences(首选项)->在搜索框输入:font—>color and font
->basic ->Text font修改大小
6、修改工作空间(项目保存的位置):
file->switch workspace
7、快捷方式:
main方法:main+alt+/ ->回车
输出语句:syso+alt+/
复制:ctrl+c
粘贴:ctrl+v
全选:ctrl+A
后退(撤销):ctrl+z
剪切:ctrl+x
保存:ctrl+s
-----------------------------------------
8、标识符(名字)的命名规则:
<1>组成:由数字,字母,下划线,$组成
<2>首字母:不能以数字开头
<3>见名知义:不要起无意义的名字(示例a,b,c等)
注:驼峰定理(当由多个单词组成时,第一个单词的首字母小写,之后每个单词的首字母
大写)
<4>关键字:不能使用java中已经占用的单词命名,如:public ,class等
注:java文件的文件名要求首字母大写
-------------------------------
9、java中的注释:
(1)单行注释: //注释内容
(2)多行注释:/*注释内容*/
(3)文档注释:/**注释内容*/ --- 生成一个项目帮助文档
-----------------------
10、数据类型:
(1)分类:基本数据类型和引用数据类型
(2)常用数据类型:
整数:int(常用),short(短整形),long(长整形)
小数:float,double(常用)
单个字符:char (给值时使用单引号)
多个字符(字符串):String (给值时使用双引号)
布尔类型:boolean (只有两个取值:true和false)
-------------------
11、变量:
(1)三要素:变量名,变量值,数据类型
(2)语法: 数据类型 变量名=变量值;
或者
数据类型 变量名;
变量名=变量值;
(3)变量的使用:
如何在输出语句中输出变量?
syso(原样输出+非原样输出(变量));
注:只要是原样和非原样之间链接,中间使用加号(+)拼接
示例:
int age=10;
char sex='男';
syso("年龄:"+age);
syso("性别:"+sex);
//syso("年龄:"+age+"性别"+sex);
----------------------------------------
<1>常量:运行期间不允许修改值
<2>语法:final 数据类型 常量名=常量值;
<3>示例: final String name="李四";
----------------------------------------
*小结:
<1>java环境的配置(jdk的安装)
<2>java跨平台原理
<3>main(程序的入口)和输出语句
<4>变量/常量的使用
<5>语法:数据类型 变量名=变量值;
<6>好处:实现程序的扩展性
----------------------------------------
1、扫描仪:用于接收用户输入的信息
步骤:
(1)创建扫描仪对象,并导入java.util.Scanner;包
Scanner input =new Scanner(System.in);
(2)调用方法扫描控制台信息
String 变量名=input.next();
int 变量名=input.nextInt();
double 变量名=input.nextDouble();
注:<1>当程序执行到input的任何方法时,都会暂停程序,
等待用户输入
<2>应该在用户接收任何值之前先给出提示语句
<3>当前代码的执行过程:从上到下依次执行
复习:
1、数据类型转换(自动/强转)
byte,short,char->int->long->float->double;
强转语法:(目标类型)数据
2、运算符:
算术运算符:+.-,*,/,%, --,++
关系运算符:>,<,>=,<=,!=,==
逻辑运算符:&&,||,!
位运算符:&,|,^,!,<<,>>(先转换成二进制再计算)
赋值运算符:=
三目运算符: 条件?表达式1:表达式2;//等价于if-else
3.java结构:
顺序,选择,循环,跳转
选择结构:
语法1:
if(条件){代码块}
语法2:
if(条件){代码块1}else{代码块2}
注:当多个条件拼接时使用逻辑运算符拼接
---------------------多分支if
语法:(在if-else后添加if或if-else结构)
if(){}else if(){}
if(){}else if(){}else{}
注:<1>不限定添加的个数
<2>if条件不能互相调换
---------------
比较是否相等:数值比较使用==,字符串比较使用"".equals("")
注:equals两侧必须是字符串类型
-------------switch选择结构:
switch(表达式){
case 常量1:
//代码
break;
case 常量2:
//代码
break;
....
default:
代码
}
注:<1>表达式的取值:int,short,byte,char,枚举类型
jdk7.0以后支持字符串类型
<2>执行过程:拿switch后的表达式和常量值逐个比较,相等时执行对应代码块
当都不满足条件时,执行default
<3>不能省略break;
------------对比switch和if结构:
<1>相同点:都是选择结构
<2>不同点:
if适用于区间判断,switch适用于等值判断
循环:
while循环:
while(循环条件){
//循环操作
}
执行特点:先判断后执行,如果第一次条件为false时,循环操作一次都不执行
-----do-while
语法:
do{
//循环操作
}while(循环条件);
执行特点:先执行后判断,如果第一次条件为false时,循环操作至少执行一次
------for循环
语法:
for(循环变量初始化1;循环条件2;循环变量的更新3){
//循环操作4
}
<1>执行过程:第一次:1,2,4,3
之后:2,4,3
<2>执行特点:先判断后执行
<3>使用场合:当循环次数固定时使用。
----------对比三种循环
(1)语法不同
(2)执行特点:while,for 先判断后执行
do-while 先执行后判断
(3)使用场合:循环次数固定:for
循环次数不固定:do-while,while
------------思路:
《1》先判断循环次数是否固定
《2》如果循环次数不固定,然后判断循环操作是否至少执行一次。
------循环嵌套:
(1)分清内外循环
(2)执行特点:外层循环执行一次,内层循环执行一遍
-----------跳转语句:
(1)break:中止程序
能控制的语句是:switch和循环
(2)continue:结束本次循环,开始下一次循环
能控制的语句是:循环
(3)return
debug:程序调试:
步骤:先打断点,然后debug as运行程序
优点:可以查看代码的执行过程以及变量值的改变
小结:
java中的结构:
顺序结构,选择结构(if,if-else,switch),循环结构(while,do-while,for)
跳转语句(break,continue,return)
-----------------------------------------
4、数组:
(1)概念:数组本身也是一个变量,但是可以同一时间存储多个数据
注:存到数组中的值要求类型相同。
(2)数组的四要素:
《1》数组名《2》数组值 《3》下标(通过下标访问数组中的数据),下标从0开始 《4》数组类型
(3)语法:
数据类型[] 数组名=new 数据类型[长度];
注:
下标的范围:0 至 (长度-1)
存取值时通过:数组名[下标]进行访问
//声明数组并对数组赋值:
语法1:
数据类型[] 数组名={值};//多个值之间使用逗号间隔
示例:
int[] ages={1,2,3,5};
语法2:
数据类型[] 数组名=new 数据类型[]{值};
示例:
int[] age=new int[]{1,2,3,4,5};
注:这里不要指定长度
(4)获取数组长度:数组名.length
遍历数组元素(访问每一个元素)
for(int i=0;i<数组名.length;i++){
}
练习:实现动态输入用户名(4个用户名)并输出
---------------------------
5、数组的应用:
(1)使用数组比较大小值
常见错误:ArrayIndexOutOfBoundsException 数组下标越界
解决方式:修改下标的范围
(2)操作数组的工具类:Arrays
常用方法:
Arrays.sort(数组名);//对数组进行升序排序
(3)对数组元素进行增删改查(遍历数据)
常见错误:NullPointerException
原因:null.equals("")或者某个字符串的值是null
复习-数组:
作用:使用一个变量保存多条数据
掌握内容:1.创建 2.存取值的方式
<1>创建数组:
<1> 数据类型[] 数组名=new 数据类型[长度];
或
数据类型 数组名[]=new 数据类型[长度];
<2> 数据类型[] 数组名={值};
<3> 数据类型[] 数组名=new 数据类型[]{值};
<2>存取值:
语法: 数组名[下标]=值;
注:下标范围:0~(长度-1)
数组的最大下标=数组名.length-1
<3>动态赋值或取值:
for(int i=0;i<数组名.length;i++){
//取值或赋值
}
<4>数组的应用:
(1)最大和最小值的获取
原理:如果数组中的某个值比最大值还大时,交换(最大值)
比最小值还小时,交换(最小值)
注:max和min的初始值要是数组中的第一个数
(2)对数组元素进行增删改查
基本思路:1.先找到要查找的元素下标
2.根据该下标对元素进行操作
注:如果是null值比较,则使用==
------------------------------------------
<5>二维数组:
电脑中不能直接识别二维数组,只能识别一维数组
二维数组的本质是在一维数组中继续添加一维数组
(1)语法:
数据类型[][] 数组名=new 数据类型[长度1][长度2];
或
数据类型 数组名[][]=new 数据类型[长度1][长度2];
注:长度1设置的是外层一维数组的长度,长度2设置的是
每一个外层一维数组中元素的长度。
定义二维数组时一定要指定最大维数即长度1
(2)遍历二维数组:
for(int i=0;i<数组名.length;i++){
for(int j=0;j<数组名[i].length;j++){
syso(数组名[i][j]);
}
}
6、面向对象开发:
<1>对象:周围具体的事物都属于对象
生活概念 java世界
外在性的描述 属性
功能性的描述 方法
<2>类:从对象中抽取共有的属性和方法
<3>对象和类的关系:
类是抽象的,对象是具体的,类是对象的集合
*小结:面向对象的概念:
对象(具体的事物),属性(外在信息),方法(功能),类(对象集合)
<4>如何通过代码实现类,对象,属性,方法
(1)定义类:
public class 类名{
//属性
//方法
}
(2)定义属性:
public 数据类型 属性名;
或者:
public 数据类型 属性名=属性值;
(3)定义方法
public 返回值类型 方法名(参数列表){
//方法体(要做的事情)
}
分类:
//有返回值方法
public 数据类型 方法名(参数列表){
//方法体
return 返回的值;
}
注:返回的值要和数据类型匹配
//无返回值方法
public void 方法名(参数列表){
//方法体
}
使用场合:
当调用完方法后,不需要给调用者返回结果时,使用无返回值方法
反之,需要给调用方法的人返回结果时,使用有返回值方法
注:参数列表可以省略
有返回值方法必须在方法体中添加return
(4)定义对象
类名 对象名=new 类名();
注:对象名自定义
调用属性: 对象名.属性名 或 对象名.属性名=属性值
调用方法: 对象名.方法名()
示例:
Scanner input=new Scanner(System.in);
注:当代码执行到方法时,会先执行方法体的内容,执行完成后返回调用该方法的界面
小结:面向对象题目的思路:
<1>先找到类以及对象
<2>找类中的属性和方法
<3>先定义该类,然后再定义测试类
注:测试类中只定义main方法,只定义属性和方法的类称为:实体类
-----补充:
当调用有返回值方法时,需要在调用的地方对返回值进行处理
return关键字用来返回到方法调用的位置、
本类中调用属性或方法时,不需要创建对象
----------练习:使用有返回值方法模拟计算器的实现过程(+,-,*,/),只讨论两个值
*小结:
(1)概念:类,对象,属性,方法
(2)定义语法:
类:public class 类名{}
对象:类名 对象名=new 类名();
属性: public 数据类型 属性名;//public 可以省略
方法:
public 返回值类型 方法名(参数列表){
//方法体
}
分类:(1)返回值的类型取值:
void(无返回值无参方法)
数据类型(有返回值无参方法)//要和return一起使用
--------------带参方法:
语法:
public 返回值类型 方法名(数据类型 参数1,数据类型 参数2){}
注:(1)参数在定义时,和变量的定义格式一致
(2)多个参数之间使用逗号间隔
(3)调用有参方法时,需要给参数赋值
使用场合:
当方法体中需要的值不能直接从属性中获取时,可以通过参数传入
优点:方法定义一次,传入参数不同效果不同
----实参和形参:
实参:调用方法时,传入的值
形参:定义方法时,参数的格式
示例:
public void test(String name){}//形参
对象名.test("abc");//实参
-----带参方法的注意事项:
当方法有多个参数时,参数的顺序要一致,个数要相同
示例:
public void test(int age,int height,String name){}
调用:
test(1,2,"");//正确
test("",1,3);//错误:类型不匹配
test(1,2);//错误:数量不匹配
方法分类:
带参:
public String test1(int age){ return ""; }
有返回值
无参
public String test2(){ return ""; }
带参
public void test3(int age){}
无返回值
无参
public void test4(){}
public static void main(String[] agrs){}
------------------成员变量和局部变量
(1)概念:定义在方法外的变量称为成员变量(成员属性)
在方法内定义的变量称为局部变量
(2)区别:
<1>作用域不同
局部变量只能作用于定义它的方法中
成员变量在整个类中都可以访问
<2>初始值不同
局部变量需要人为指定默认值
成员变量有默认值
注:在同一类中,如果局部变量和成员变量重名时,局部变量具有更高的优先级
(3)数据类型:byte,short,int,long,double ,float,char,String,boolean
(4)数据分类:
<1>基本数据类型:(8种)
byte,short,int ,long,double ,float,char,boolean
<2>引用数据类型:(3种)
类(String),数组,接口
注:基本数据类型和引用数据类型作为方法参数时,传递方式:
基本数据类型传递的是值,引用数据类型传递的是地址。
复习-面向对象开发:
(1)概念:类(对象的集合),对象(具体的事物),属性(外在描述),方法(功能性描述)
类和对象的关系:类是抽象的,对象是具体的,类是对象的集合
(2)定义方式:
《1》定义类:
public class 类名{
//属性和方法
}
注:类名要求首字母大写
《2》定义属性:
public 数据类型 属性名;
或:
public 数据类型 属性名=属性值;
注:public是可以省略的,属性的定义和变量定义格式一样
《3》定义方法:
public 返回值类型 方法名(数据类型 参数名1,数据类型 参数名2){
//方法体
}
注:(1)返回值类型的取值:
<1>数据类型(11种)
基本数据类型:byte,short,int,long,float,double,char,boolean
引用数据类型:类(String),数组,接口
方法体中必须有return,要求return后返回的值要和数据类型匹配
<2>void(无返回值)
(2)方法名自定义
(3)参数列表:多个参数之间使用逗号间隔
----------对于方法的定义,当方法体中需要的变量,在本类中不能直接获取到时,可以通过参数传入到方法中
《4》属性和方法的调用(定义对象)
注:在调用属性和方法前一定要创建属性或方法所在的类的对象
定义对象:
类名 对象名=new 类名();
调用属性或方法:(通过点(.)操作符)
对象名.属性名
对象名.方法名();
---------------新内容:
补充:toString()
默认情况下,如果输出对象名,则会输出该对象的地址
示例:
Student stu=new Student();
syso(stu);//输出对象的地址,等价于:syso(stu.toString());
当输出对象时,会自动调用toString()方法,我们可以修改toString()方法进而修改输出内容
在类中重新定义:
//方法格式固定,返回内容可以修改
public String toString(){
return "";
}
---------------带参方法
(1)使用数组作为参数
(2)使用类作为参数
当带参方法中,多个参数都属于同一个类的属性时,可以将参数改为该对象
示例:
public class Student(){
int age;
String name;
}
public class Test{
public void add(Student s){}//将对象作为参数
}
优点:只声明了一个对象,但是可以通过该对象来获取到N个属性
-------------对象数组(添加/查看数据)
数组: 数据类型[] 数组名=new 数据类型[长度];
int[] 数组名,String[] 数组名
对象数组:
(1)作用:可以同时存储多个对象
(2)语法:
类名[] 数组名=new 类名[长度];
注:声明的是哪个类,那么该数组就只能存储哪个类的对象
示例:
Student[] stus=new Student[5];//声明对象数组
Student s=new Student();//创建对象
stus[0]]=s;//正确
Teacher t=new Teacher();
stus[1]=t;//错误:数组的类型是Student
对象数组:
数组中保存对象,对象中保存属性
字符串数组:
数组中直接保存数据
//String[]
注:对象数组在使用前,一定要给数组中的元素传入对象。
-----------------补充循环:
增强for循环:
for(数据类型 变量名:数组名){//循环操作}
原理:自动将数组中的元素逐个提取并赋给前面声明的变量
注:这里的数据类型要和数组中保存的元素的数据类型要相同。
-----------------方法重载:
构造方法:
语法: public 类名(数据类型 参数1,数据类型 参数2){}
调用时机:new对象时,自动调用默认的无参构造
注:任何一个类都默认存在一个无参构造
示例:
public Student(){}//无参构造
注:当用户自定义了一个构造方法后,原来默认的无参构造就被覆盖
所以通常情况下,如果用户自定义构造方法,需要手动把无参构造补充出来
作用:给类中的属性赋值
*小结: 类的定义格式:
public class 类名{
//属性
//有参和无参构造方法
//普通方法
}
方法重载:(OverLoad)
在同一个类中,方法名相同,参数列表不同(数量,顺序,类型),则
把这些方法称为方法重载(构造方法和普通方法都可以实现重载)
注:方法重载和参数名无关。
------------对属性赋值的方式:
(1)对象名.属性名=属性值;
(2)定义属性时直接赋值
(3)构造方法赋值
(4)通过封装:
好处:保证了数据的安全性和有效性
概念:将属性私有化(private),提供公有方法(setter/getter)访问私有属性
快捷方式:alt+shift+s -> getter and setter
面向对象的三大特征:封装,继承,多态
--------------
练习题:创建对象数组,将3名学生的信息(名字,年龄)添加到数组中,并实现遍历
赋值实现方式:1.对象.属性名
2.通过构造方法赋值
3.使用封装方式赋值
复习:
(1)面向对象:类,对象,属性,方法
(2)对象数组:
语法:类名[] 数组名=new 类名[长度];
数组名[下标]=对象;(对象中通过属性的方式存值)
(3)面向对象中存值得方式:
<1>直接给属性赋值
<2>对象名.属性名=值
<3>通过构造方法
语法:
public 类名(参数){}
注:任何一个类中默认存在一个无参构造,当自定义构造时,默认的无参构造会被覆盖
调用时机:new对象时调用构造方法
(4)封装:将属性私有化,提供公有方法访问私有属性
private String user;
//存值
public void setUser(String user ){
this.user=user;
}
//取值
public String getUser(){
return user;
}
(5)方法重载:
在同一个类中,方法名相同,参数列表不同(数量不同,类型不同,顺序不同)
这时这几个方法就可以称为方法重载
体现:构造方法重载
---------------------------------------
(1)package:包
作用:1.区分同名文件(同一包下不允许有同名文件,不同包可以)
注:package代码必须在java文件的第一行,前面不能添加代码,注释除外
导包:import 包名.类名;
public,import,package的出现顺序:package,import,public
(2)访问修饰符:
作用:设置属性,方法,类的访问权限
内容:
同一类中 同一包中 子类中 任何地方(同一项目中)
private √
默认访问修饰符 √ √
protected √ √ √
public √ √ √ √
(3)static修饰符:
作用:表示静态的,用于修饰属性和方法,提升访问等级,
static修饰完的属性可以直接通过类名调用
语法:
static 数据类型 属性名;
public static 返回值类型 方法名(){}
调用时:
类名.属性名
类名.方法名()
示例:Arrays.sort();
注:static修饰的属性或方法可以用对象名调用,但是不建议这么调用
在同一类中,静态方法中访问的属性要是静态属性
(4)this关键字:
概念:表示当前类的一个对象的引用
作用:解决同名变量的问题
示例:
public void setName(String name){
this.name=name;
}
扩展作用:
调用普通方法: this.方法()
调用构造方法: this();//调用当前类的无参构造
this(参数值);//调用当前类的有参构造
注:this只能在当前类中使用
构造方法互相调用时,调用的代码必须是当前方法体中的第一行
示例:
public Student(){
this("");//调用当前类的有参构造
syso();//其他操作
}
-------------------------------
(6)继承:
(1)作用:实现代码的重用性,将子类中共有的属性或方法提取到父类中
(2)特点:单继承(一个类只能继承一个父类),体现的是类与类之间的关系
(3)语法:
public class 类名 extends 父类类名{
//属性或方法
}
注:当前类也可以称为子类
(4)优点:父类的内容子类可以直接调用,但父类对象不能调用子类中的内容
---------------------
(7)方法重写:
<1>定义:
在子类中,存在和父类中方法格式相同的方法时,那么就称子类的方法重写了父类的方法
<2>使用场合:当子类的方法有自己的实现内容时,可以重写父类方法,而不需要重新定义新方法
<3>执行过程:当父类和子类存在重写方法时,子类对象先调用当前类中的方法,如果没有该方法
则去父类中查找
<4>补充:验证子类中方法是否重写父类:
在方法上添加@Override
示例:
@Override
public void test(){}
例题1:构造方法是否可以重写?不能
原因:构造方法要求方法名和类名相同,但是方法重写要求重写的方法和 被重写方法的方法名一致。
--------------------------
(8)super关键字:
<1>作用:表示一个父类对象的引用
<2>使用场合:在子类中使用
<3>语法:
调用属性:super.父类属性名;
调用方法:super.父类的方法名();
调用构造:super();//调用父类的无参构造
super(参数值);//调用父类的有参构造
<4>继承时构造方法的调用:
(1)默认情况下,子类先调用父类的无参构造
(2)当子类中显式调用父类的其他构造时,默认调用的无参构造就不执行了
(3)当子类中显式调用自身构造方法时,先执行自身构造,然后按照上两条执行
----------
(9)所有类的顶级父类:Object类
常用方法:equals()
toString()
超类=父类
-----------------
(10)多态:
<1>当参数声明成父类对象时,传递的值可以是子类对象或者父类对象
示例:
public void test(Pet pet){}//声明父类参数
对象名.test(new Dog());//传递子类对象
说明:程序会自动将子类转换父类,实现向上转型
<2>多态:多种表现形态
实现原理:同一个对象引用,通过传入不同的参数,进而实现不同的结果
表现形式:将父类声明作为参数
*多态的三要素:
1.继承关系
2.方法重写
3.用父类作为参数
方法重写是实现多态的基础。
示例:
public class Pet{
public void test(){}
}
public class Dog extends Pet{
@Override
public void test(){syso("test1")}
}
public class Cat extends Pet{
@Override
public void test(){syso("test2")}
}
public class Master{
public void duotai(Pet pet){ //将父类作为参数
pet.test(); //调用重写的方法
}
}
测试类:
Dog dog=new Dog();
Master m=new Master();
m.duotai(dog);//传递子类对象 ,运行结果test1
---------------------向上(子类转父类),向下(父类转子类)转型
(1)向上转型:
方式1:父类作为参数,传递子类对象(上面示例)
方式2:声明父类对象,传递子类
父类类名 对象名=new 子类类名();
示例:
Pet dog=new Dog();//多态的表现形式
注:向上转型后,该对象不能调用子类独有的方法或属性,只能调用
父类方法,属性以及子类重写父类的方法
注:如果创建的类有父类时,习惯上声明父类对象,new子类对象
示例:
Pet cat =new Cat();
Pet dog=new Dog();
(2)向下转型:
目标类型 对象名=(目标类型)对象名
示例:
Pet pet=new Dog();//向上转型
Dog d=(Dog)pet;//向下转型
注:不是任何类之间都能进行向上/乡下转型,要求类型要匹配
示例:
Pet pet=new Dog();
Dog dog=(Dog)pet;//正确
Cat cat=(Dog)pet;//编译时错误,类型不匹配ClassCastException
判断对象和类是否有关系:
对象名 instanceof 类名
示例:
Pet pet=new Cat();
if(pet instanceof Dog){
System.out.println("有关系,可以强转");
}else{
System.out.println("不能强转");
}
复习:oo(面向对象)
(1)概念:类,对象,属性,方法
类和对象的关系:类是抽象的,对象是具体的,类是对象的集合
(2)定义格式:
类:
public class 类名{}//类名首字母大写
对象:
类名 对象名=new 类名();//只要调用属性或方法前就需要创建对应类的对象
调用属性:
对象名.属性名
调用方法:
对象名.方法名()
构造方法:
public 类名(参数列表){}
(3)给属性赋值:
(1)定义属性时赋值
(2)对象名.属性名=属性值
(3)构造方法:通过参数赋值
(4)封装:setter/getter进行赋值(常用)
(4)java中三大特性:封装,继承,多态
<1>封装:
将属性私有化,提供公有的方法访问私有的属性
作用:保证属性(数据)的安全性和有效性
示例:
private String name;
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
<2>继承:体现类与类之间的关系
语法:
public class 子类(类名) extends 父类类名{}
作用:实现代码的复用
方法重写:
在子类中存在和父类方法一致的方法,就称为子类重写了父类的方法
<3>多态:
同一引用(声明父类变量)中,通过传入不同的实例(new子类对象),从而实现不同的效果
作用:实现代码的扩展性
三要素:1.继承关系 2.方法重写 3.父类作为参数
补充:向上向下转型:
向上转型:声明父类对象,传递子类实例
Pet pet1=new Dog();
Pet pet2=new Cat();
向下转型:
类名 对象名=(目标类型)已经向上转型后的对象名
示例:
Dog dog=(Dog)pet1;
instanceof:判断对象和后面的类是否存在关系
示例:
if(pet1 instanceof Dog){
Dog dog=(Dog)pet1;
}else if(pet1 instanceof Cat){
Cat cat=(Cat)pet1;
}
-------------------------------------------------
多态的应用:
1.创建对象时,声明父类,new子类对象
2.将父类作为形参,通过传递不同子类对象,实现不同效果
3.将父类作为返回值类型使用
------------------------------抽象方法和抽象类
1. 抽象方法:没有方法体的方法,连大括号都没有的方法,使用abstract修饰
示例:
public abstract void test();
注:这里不能添加大括号,抽象方法必须在抽象类中
2. 抽象类:有抽象方法的类是抽象类,但是抽象类中不一定存在抽象方法.
抽象类中包含的内容:属性,普通方法,构造方法,抽象方法
注:抽象类不能实例化(即不能创建对象)
语法:
public abstract class 类名{}
3.抽象方法或抽象类的使用场合:
当子类有自己的实现方式时,则可以将该方法定义成抽象方法,对应的类也就成了抽象类
------------------------接口(特殊的抽象类)
1.接口的定义:
public interface 接口名{
//抽象方法
}
注:接口中只定义方法的格式,没有方法的实现,具体的实现内容由实现类添加
接口不能实例化
2.实现类:
public class 类名 implements 接口名{
//要求实现接口中的所有方法
//这个类中可以定义普通方法或抽象方法
}
3.创建实现类对象:
接口名 对象名=new 实现类的类名();
示例:
UserInterface u=new User();
4.对比接口和抽象类:
相同点:都不能实例化
不同点:
1.语法;
抽象类:
public abstract class 类名{}
接口:
public interface 接口名{}
2.包含内容不同:
抽象类中可以包含普通和抽象两种方法,而且抽象方法需要使用abstract修饰
接口中只能定义抽象方法,无需abstract修饰
接口中定义的属性默认都是常量,定义常量名时习惯全部字母大写。
-----------------------小结:
概念:类,对象,属性,方法,继承,封装,多态,抽象类,接口
方法重写,方法重载,静态方法(static)--由类名直接调用,构造方法
修饰符 (对象数组)
掌握内容:1.语法 2.示例代码
--------------------继承和实现同时出现:
1.java中单继承,多实现,且是先继承后实现
2.
public class 类名 extends 父类 implements 接口1,接口2{
//代码
}
注:多个接口之间使用逗号间隔
--------------------
补充:1.接口中的属性可以直接使用接口名调用
2.接口中定义的方法都是public的,所以实现类中不能缩小方法的访问权限
3.接口中的属性修饰符:
public static final 数据类型 常量名=值;
public,static,final三个修饰符可以互换位置
public static final int age1=10;(√)
public final static int age2=10;(√)
static public final int age3=10;(√)
final public static int age4=10;(√)
补充2:
接口的实现类可以实现接口的所有方法,也可以实现部分方法,但是该实现类要变成抽象类
(原因:有抽象方法的类称为抽象类)
编译时异常
运行时异常
---------异常:
1.java中自带异常处理机制,用于处理运行期间可能发生的异常
2.处理异常的关键字:
try ---定义可能发生异常的代码
catch ---- 捕捉已经发生的异常
finally --- 无论是否发生异常都会执行的代码
throw ---- 抛出异常
throws ---- 声明异常
3.语法:
try{
//可能发生异常的代码
}catch(异常类型 参数名){
//捕捉到异常后的处理方式
}finally{
//始终要执行的代码
}
注:多重catch时,异常类型是从特殊到一般,即从子类到父类
4.数值类型的字符串转换成数值
Integer.parseInt(String);//这里的String需要保存的是数字
示例:
String str="123";
int num=Integer.parseInt(str);
5.finally中唯一一种不执行的情况:
System.exit(1);//作用:强制退出虚拟机
6.throws:用于声明异常,告诉调用方法的代码,该方法可能会发生的异常
注:1.定义的位置是在方法后面
2.多个异常之间使用逗号间隔
3.处理方法抛出的异常方式有两种:1)继续往上抛,直到抛给虚拟机
2)使用try/catch处理异常
示例:
public void a() throws NullPointerException,Exception{}
7.throw:用于抛出异常,在方法的代码块中定义,后面跟异常类的对象
示例:
throw new Exception("异常信息");
注:当方法体中存在throw时,需要对throw进行处理,
处理方式1:在方法后添加throws,声明异常
处理方式2:在方法中直接try-catch捕捉异常
使用场合:当程序员需要自己抛出异常时
8.自定义异常实现步骤;
1.定义异常类:要求该类继承Exception或RuntimeException
2.在异常类中定义有参构造,该构造中再调用父类有参构造
示例:
public class AgeException extends Exception {
//message表示错误信息
public AgeException(String message){
super(message);
}
}
3.在throw异常时,new该异常类的对象
示例:
throw new AgeException("错误信息");
----------------------------总结:
1.类:保存由多个对象中抽取的共有的属性或方法
语法:
public class 类名{
//属性和方法
}
2.属性:本质上就是在定义变量,外在描述叫属性
3.方法:对象能做的事情
<1>构造方法:
public 类名(数据类型 参数名1,数据类型 参数名2){
//将参数值赋给属性
}
作用:给属性赋值
调用时机:new对象时,默认调用无参构造
<2>普通方法:
public 返回值类型 方法名(数据类型 参数名){
//方法体
}
注:方法的返回值类型
4.如何调用属性和方法:
<1>调用普通方法或属性:先new对象,然后通过对象调用
创建对象:类名 对象名=new 类名();
调用属性:对象名.属性名
调用方法:对象名.方法名();
<2>调用静态(static)属性或方法:通过类名直接调用
示例:
Arrays.sort();
public static int age;
public static void test(){}
5.java的三大特性:封装,继承,多态
<1>封装:
private 数据类型 属性名;
//赋值
public void set属性名(数据类型 参数名){
this.属性名=参数名;
}
//取值
public 数据类型 get属性名(){
return 属性名;
}
alt+shift+s:getter setter
<2>继承:体现类与类之间的关系
public class 类名 extends 父类名{}
优点:子类对象可以直接访问父类的属性或方法
默认情况下任何类的父类都是Object
<3>多态:申明父类对象,传递子类实例或申明接口对象,传递实现类的实例
多态的三要素:1.继承 2.方法重写 3.父类作为参数
public class Father{
public void a(){}
}
public class Son1 extends Father{
public void a(){}//方法重写
}
public class Son2 extends Father{
public void a(){}//方法重写
}
public class Test{
public void test(Father f){
f.a();//通过父类对象调用重写的方法
}
}
使用场合:1.将父类或接口作为参数
2.创建对象时,使用父类或接口声明对象
3.返回值类型写的是父类类型或接口类型
6.抽象类和接口
抽象类:
public abstract class 类名{
//属性
//普通方法
//抽象方法
public abstract 返回值类型 方法名(参数);
}
使用场合:
当父类中定义的方法,方法体没有实际意义时,或子类有各自的实现方式时,
该方法可以定义成抽象方法
接口:(特殊的抽象类)
接口中定义的方法都是抽象方法(访问修饰符是public),属性都是静态常量
接口:只定义方法的格式,而没有方法的实现
public interface 接口名{
//抽象方法或常量
}
实现类:实现接口中的内容
public class 类名 implements 接口名{
//实现接口中的方法
}
注:一个实现类可以实现多个接口
java特点:单继承,多实现
public class 类名 extends 父类 implements 接口1,接口2{}
7.异常处理:
try-catch-finally 用于处理异常
throw 用于抛出异常
throws 用于声明异常
8.接口和抽象类的使用场合:
抽象类:大多出现于父类,当父类中定义的方法,每个子类都有各自的实现时
那么该方法就可以定义为抽象方法,有抽象方法的类进而是抽象类
接口:多用于方法的定义,而不实现,当出现一部分子类方法内容相同,则可以选择
接口进行优化(例如愤怒小鸟中鸟的叫声)
重点:
类,对象,调用属性,调用方法,继承关系,封装,接口和实现类
1.集合:用于保存多条数据,所在包:java.util
接口:
Collection
List Set map
实现类 ArrayList HashSet HashMap
LinkedList
2.List接口:
(1)List的存储特点:不唯一(可重复),有序(插入的顺序)
(2)ArrayList:
本质上就是一个长度可变的数组,查询或随机访问数据时效果高
存储方式:顺序存储
(3)LinkedList:
存储方式:链式存储(同时存储数据以及下一个数据的地址)
插入或删除数据时效率高
(4)使用集合的优点:长度可变,并且保存的数据类型不限定
(5)ArrayList的常用方法:
添加元素:add(元素)
给指定下标添加元素:add(下标,元素)
查看集合中的元素: get(下标)
获得集合的长度:size()
替换指定下标的元素:set(下标,替换的值)
删除指定下标的元素:remove(下标)
判断集合是否为空:isEmpty()
判断集合是否包含某元素:contains(元素)
获得某元素在集合中的下标:indexOf(元素)
注:当未找到元素下标时,返回-1
(6)LinkedList独有的方法:
注:arrayList中的方法,LinkedList都可以调用
独有方法:
addFirst(元素)
addLast(元素)
getFirst()
getLast()
removeFirst()
removeLast()
如果想要调用这几个独有的方法,需要在声明对象的时候
声明成LinkedList
即:
LinkedList list=new LinkedList();
-----------------------------------
User类
用户名(name),密码(password),年龄(age)
创建该类:
1.三个属性
2.两个构造(一个无参,一个全参)
3.定义show方法,负责显示用户名和密码
测试类:Test_user
要求:1.创建用户对象,通过构造方法给属性赋值
2.调用show方法
public class User{
//属性
public String name;
public String password;
public int age;
//构造
public User(){}
public User(String name,String password,int age){
this.name=name;
this.password=password;
this.age=age;
}
//方法
public void show(){
syso(name+password);
}
}
public class Test_User{
public static void main(String[] args){
User u=new User("张三","123",18);
u.show();
}
}
-------------------------------
定义类:
public class 类名{
//1.属性
访问修饰符 数据类型 属性名 [="属性值"];
//2.构造方法(一个无参,一个全参)---只负责给属性赋值
public 类名(){}
public 类名(数据类型 参数名){
this.属性名=参数名;
}
//3.普通方法
访问修饰符 返回值类型 方法名(参数列表){
//方法体,注:当返回值类型是有返回值时,方法体必须添加return
}
}
测试类:带有main方法
public class 类名{
public static void main(String[] args){
//测试代码:给属性赋值或调用方法--前提条件:创建对象
//1.创建对应类的对象,对象名自定义
类名 对象名=new 类名();//在调用构造方法,给具体的值
//2.调用属性或方法
对象名.属性名
对象名.方法名();
}
}
类图:
第一行:类名
第二行:属性
属性名:属性类型
第三行:方法
方法名:方法的返回值类型
------------------------------封装:
作用:设置属性存值(set)和取值(get)的权限
实现:
private 数据类型 属性名;
//set
public void set属性名(数据类型 参数名){
this.属性名=参数名
}
//get
public 数据类型 get属性名(){
return 属性名;
}
--------------------------封装后赋值取值:
对象名.set属性名(属性值);
对象名.get属性名();
-----------练习:
1. 使用程序描述:
创建一个封装良好的类Employee员工,
包含姓名name,工资salary属性,另外再书写一个方法getMoney,返回该员工工资。
创建一个Manager类,从Employee继承,包含奖金bonus属性,实现getMoney方法,
返回其salary与bonus的和
public class Manager extends Employee{
private double bonus;
public void setBonus(double bonus){
this.bonus=bonus;
}
public double getBonus(){
return bonus;
}
public double getMoney(){
return super.getMoney()+bonus;
}
}
public class Employee{
private String name;
private double salary;
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
public void setSalary(double salary){
this.salary=salary;
}
public double getSalary(){
return salary;
}
public double getMoney(){//返回员工工资
return salary;
}
}
2.建立一个人类(Person)功能要求:
a)Person中包含4个私有型的数据成员name,addr, sex,age分别为字符串,
字符串,字符及整型。表示:姓名、地址、性别和年龄。
一个四参构造函数,一个两参构造函数,一个无参构造函数,
一个输出函数用于显示四种属性。
public class Person{
private String name;
private String addr;
private char sex;
private int age;
public Person(){}
public Person(String name,String addr){
this.name=name;
this.addr=addr;
}
public Person(String name,String addr,String sex,int age){
this.name=name;
this.addr=addr;
this.sex=sex;
this.age=age;
}
public void show(){
syso(name+addr+sex+age);
}
}
//继承:
public class A{
private A(){}
public A(String name){}
}
public class B extends A{
public B(){
super("zhangsan ");
}
}
-----------------------------------
3.租车系统
定义一个汽车类 有属性:车名,租金,
有方法:计算租金
方法模型(public double calc(int days){})
定义测试类
实例化汽车类对象
输入车名和租金,输入租车天数打印出总租金
public class Car{
//属性:车名,租金
private String carName;
private double money;
//方法:计算租金
public Car(){}
public Car(String carName,double money){
this.carName=carName;
this.money=money;
}
public double calc(int days){
return days*money;
}
}
Student类:
公有属性:姓名(name),性别:sex
定义构造方法:一个无参,一个全参
定义print方法,显示用户名和性别
测试类中:
创建学生类对象,使用对象调用属性和构造方法两种方式创建两个
学生对象,并调用print方法显示用户信息
public class Student{//实体类
public String name;
public char sex;
public Student(){}
public Student(String name,char sex){
this.name=name;
this.sex=sex;
}
public void print(){
syso(name+sex);
}
}
public class Test{
public static void main(String[] args){
Student s1=new Student();
s1.name="";
s1.sex='';
Student s2=new Student("",'');
s1.print();
s2.print();
}
}
-------------------------集合:
1.集合接口:Collection(List,Set),Map
实现类:List(ArrayList,LinkedList)
Set(HashSet)
Map(HashMap)
2.List中常用方法:(添加数据/查看数据)
add(Object obj);//添加数据
get(i);//查看数据
size();//获得集合长度
3.遍历集合:
(1)普通for循环
for(int i=0;i<集合.size();i++){
Object obj=集合.get(i);//注:如果保存的是对象,需要向下转型
}
(2)增强for循环(foreach)
for(Object obj:集合){
//直接使用obj,不需要调用get(i)方法
}
4.Set -- HashSet
存储特点:唯一,无序
注:set没有get()方法
常用方法:
add(Object obj);//添加数据
size();//获得长度
iterator();//获得迭(die)代器
遍历:
方式1:foreach循环
for(Object obj:集合名){
//操作obj
}
方式2:使用迭代器:
//1.获得迭代器对象
Iterator it=集合名.iterator();
//2.调用迭代器中的hasNext()方法判断是否有下一个
while(it.hasNext()){
Object obj=it.next();//调用next()获得集合中的每一个元素
//开始操作obj
}
练习:
创建一个用户类(User),包含公有属性:name,password
定义两个构造(无参和全参)以及打印用户信息的print()方法
测试类:
使用set集合保存三名用户信息,并使用两种方式遍历该集合中的元素
----------------------------------Map--HashMap
1.存储方式:键值对存储(key-value)
2.要求:key值不允许重复,value值可重复
3.查找数据的方式:通过key值找value值
默认情况下,key和value都是Object类型的
4.常用方法:
存值:put(key,value)
取值:get(key)
key值集合:keySet();//返回类型:Set
value值集合:values();//返回类型:Collection
注:遍历Collection可以使用迭代器
containsKey(key):判断key值是否存在于map集合中
5.value值的遍历方式:
(1)通过key查找value
get(key);
(2)直接获得value值的集合
Collection values=map.values();//然后通过iterator遍历
或将value值的集合添加到list集合中
List list=new ArrayList(map.values());
-----------小结:
1.java中三大集合:List,Set,Map
2.创建集合对象时:
接口名 对象名=new 实现类名();
示例:
List list=new ArrayList();
List list2=new LinkedList();
Set set=new HashSet();
Map map=new HashMap();
3.掌握内容:存值和取值
list:
存值:add(对象)
取值:get(下标)
set:
存值:add(对象)
取值:iterator():Iterator
方法:hasNext() 判断迭代器中是否有下一个元素
next() 获得迭代器中的单个元素
map:存值:put(key,value)
取值:get(key)
4.无论存到哪一个集合,存入的数据都会向上转型(转成Object类型)
所以从集合中获取值时需要向下转型
----------------泛型
作用:限定添加到集合中的数据的类型,保证了该集合中类型的统一
防止了用户在取出数据时需要强转的问题
格式:
接口<数据类型> 对象名=new 实现类<数据类型>();
示例:
List<Student> list=new ArrayList<Student>();
或
//表示key必须是String,value值必须是User类的对象
Map<String,User> map =new HashMap<String,User>();
-------工具类:Collections(针对于集合的工具类)
Arrays ---对数组的工具类
Collections.sort(List集合);//升序排序
对比Collection 和Collections:
Collection是List和Set的父接口,
Collections是操作集合的工具类
--------
switch(表达式)
表达式的数据类型:int,short,byte,char,枚举类型,String(jdk7.0)
----------枚举类型:用于定义一组常量
格式:
public enum 枚举名{
枚举值//多个枚举值之间使用逗号间隔
}
调用枚举值:枚举名.枚举值
示例:
public enum Gender{
BOY,GIRL //枚举值默认是static,final
}
调用:Gender.BOY
使用场合:当需要定义一些常量值时,可以将这些常量值放在枚举中
优点:保证数据的安全性
注:在switch中case后面的枚举值不需要使用枚举名调用,但是
枚举值必须是在switch所使用的枚举范围内列举
示例:
public enum Classes{
U1,U2,U3
}
Test:
Classes cla=Classes.U1;
switch(cla){}//里面的switch只能是U1,U2,U3这三个值
补充:枚举值之间比较相等使用==
--------------------------包装类和基本数据类型
包装类:将基本数据类型封装到一个类中,并提供属性或方法
对比图:
基本数据类型
byte int short long float double char boolean
包装类:
Byte Integer Short Long Float Double Character Boolean
注:包装类所在的包:java.lang
常用方法:
Integer.parseInt("");
Double.parseDouble("")
Float.parseFloat("")
作用:将字符串类型的数值转换成基本数据类型的值
--------------------------Math和Random
Math:算数类,用于数学中的计算公式
常用方法:
Math.random();//生成0-1(大于等于0,小于1)之间的值
Random:机数类(注:调用方法时先创建对象)
常用方法:
nextInt(int n);//返回0-n之间的值(大于等于0,小于n)
示例:
Random ran=new Random();
ran.nextInt(33);//0-33之间的值
----------------------String类
常用方法:
length():获得字符串长度
equals(""):比较字符串是否相等(严格区分大小写)
concat(""):拼接字符串,等价于“+”
toLowerCase():大写转小写
toUpperCase():小写转大写
equalsIgnoreCase():忽略大小写的比较
indexOf(""):获得要查找的字符串第一次出现的下标
lastIndexOf(""):获得查找字符串最后一次出现的下标
subString(int begin,int end);截取字符串
注:(1)这里写的是下标值,从0开始
(2)截取时包含开始位置的值,不包含结束位置的值
trim():去除字符串的两侧空格
split("分割条件");将字符串按照分割条件分割成字符串数组
---------------StringBuffer(String的增强版)
1.定义:
StringBuffer s=new StringBuffer();
赋值:
s.append("");
注:StringBuffer的值不能直接赋给String类型
需要调用toString()方法
2.对比String 和StringBuffer
String :
长度不可变,当用户修改字符串时,每次都会开辟新空间保存
修改后的数据
StringBuffer:
长度可变,无论字符串修改几次,使用的都是同一内存
3.常用方法:
insert(插入的下标,插入的内容);往字符串中插入字符
-----------------Date类和SimpleDateFormat类
//1.获得系统时间
Date date=new Date();
//2.格式化日期
SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
注:(1)注意字母的大小写 (2)hh表示12进制,HH表示24进制
//3.开始格式化日期
String s=sf.format(date);
注:格式化后以字符串方式返回结果
-------------Calendar类:
作用:指定时间,并且可以获取该时间所属的星期,月份等
定义:
//获得Calendar对象
Calendar cal=Calendar.getInstance();
//获得某些字段的值
cal.get(字段);//注:字段值是Calendar中的静态值
示例:
int year=cal.get(Calendar.YEAR);
cal.set(字段,值);//用于修改日期
----总结:
底层类:
(1)枚举类型(定义了一组常量值)
(2)包装类(对基本数据类型进行封装,提供了属性或方法)
(3)Math 算数类
Math.random();
Random类
nextInt(数值);
(4)String,StringBuffer
常用方法:
length(),equals(),concat()
indexOf(),subString(),lastIndexOf()
(5)Date,Calendar--操作日期
-----总结(本周):
(1)抽象类和接口(重点)
interface,implements
(2)异常:try-catch-finally
throw
throws
(3)集合:
List,Set,Map
验证方式:三种集合存值和取值操作(存取对象)
(4)实用类
--------补充:
方法的定义格式:
public 返回值类型 方法名(参数){
//方法体
}
分类:
无返回值:void
有返回值:11种数据类型,
注:要在方法体中添加return
//1.byte
public byte a(){
byte b=0;
return b;
}
//2.int
public int a(){
return 1;
}
//3.short
public short a(){
return 1;
}
//4.long
public long a(){
return 1;
}
//5.float
public float a(){
return 1.0;
}
//6.double
public double a(){
return 1.0;
}
//7.char
public char a(){
return '';
}
//8.boolean
public boolean a(){
return true;
}
//9.类(Student)
public Student a(){
return new Student();
}
//10.数组(String[])
public String[] a(){
return new String[4];
}
//11.接口(UserDao-接口名 UserDaoImpl--实现类)
public UserDao a(){
return new UserDaoImpl();
}
1.File类:用于创建文件或文件夹,所在包:java.io包
常用方法:
(1) exists();//判断文件或文件夹是否存在
(2) mkdir();//创建单个文件夹
(3) mkdirs();//创建多个文件夹(父文件夹不存在也可以创建)
(4) createNewFile();//创建文件
(5) File(String path):
//File类的构造方法,path表示文件或文件夹路径
(6)getName();//获得文件或文件夹名称
(7)isDirectory();//判断是否是文件夹目录
(8)isFile();//判断是否是文件
(9)listFiles():File[] ;//获得某个目录下的文件或文件夹对象
示例:
File f=new File("d:\\a\\c");//f表示文件夹目录
File f2=new File("d:\\test.txt");//f2表示文件目录
2.io流:用于程序和文件之间进行信息交互
分类: 输入流(InputStream和Reader)
1.按流向分:
输出流(OutputStream和Writer)
注:流向以程序为出发点
2. 字节流(InputStream和OutputStream)
按操作对象分:
字符流(Reader和Writer)
3.字节流的输入和输出
(1)字节流的输入(读取):
//1.创建FileInputStream对象
FileInputStream fis=
new FileInputStream("文件路径");
//2.调用read()方法读取信息(每次读一个字节)
int num=fis.read();
while(num!=-1){
syso(num);
num=fis.read();
}
//3.关闭流
fis.close();
(2)字节流的输出(写入):
//1.创建FileOutputStream对象
FileOutputStream fos=new FileOutputStream("文件路径",是否拼接);
//2.调用write()方法写入文件
String str="";
byte[] b=str.getByte();
//参数含义:写入的数组,开始位置,写入长度
fos.write(b,0,b.length);
//3.关流
fos.close();
4.字符流输入和输出:
(1)字符输入流
//1.创建对象
FileReader fr=new FileReader("文件路径");
BufferedReader br=new BufferedRear(fr);
//2.调用readLine()方法
String str=br.readLine();
while(str!=null){
syso(str);
str=br.readLine();
}
//3.关流
br.close();
fr.close();
(2)字符输出流:
//1.创建对象
FileWriter fw=new FileWriter("文件路径");
BufferedWriter bw=new BufferedWriter(fw);
//2.调用write()方法
String str="";
bw.write(str);
//3.关流
bw.flush();//刷新缓冲区
bw.close();
fw.close();
练习:
使用字节流和字符流分别实现文件的复制,示例:c盘下有一个已存在的文件text.txt
要求将该文件使用程序的方式复制到d:\\temp文件夹下(复制内容包含文件和文件内容)
小结:
File类:用于操作文件或文件夹
字节流:
基类:InputStream,OutputStream
子类:FileInputStream ,FileOutputStream
字符流:
基类:Reader ,Writer
子类:FileReader,FileWriter
BufferedReader,BufferedWriter
5.序列化和反序列化:
作用:永久性的保存java对象信息
概念:
序列化:通过io流的方式,将java内存中的对象保存到文件中
反序列化:通过io流,将文件中的java对象信息读取到程序中
实现:
序列化:
java.io.NotSerializableException
步骤:
1.在要保存的对象的类中实现Serializable接口
2.创建ObjectOutputStream对象
FileOutputStream out=new FileOutputStream("文件路径");
ObjectOutputStream oos=new ObjectOutputStream(out);
3.创建要保存的对象,调用writeObject(Object obj)方法
oos.writeObject(new Student());
4.关流
oos.close();
out.close();
复习:
io流:
(1)File类:操作文件或文件夹
(2)io流:
字节流:
InputStream(FileInputStream)
OutputStream(FileOutputStream)
字符流:
Reader(BufferedReader,FileReader),
Writer(BufferedWriter,FileWriter)
(3)序列化(将java以io流的方式写入到文件中)和反序列化:
序列化:
<1>实体类实现序列化(Serializable)的接口
<2>ObjectOutputStream类
调用writeObject(Object obj);
--------------------------------------------
反序列化步骤:
<1>创建ObjectInputStream类对象
FileInputStream in=new FileInputStream("文件路径");
ObjectInputStream ois=new ObjectInputStream(in);
<2>调用readObject():Object obj方法
Object obj=ois.readObject();//必须时向下转型
<3>关流(最好在finally中添加)
ois.close();
in.close();
注:(1)反序列化只能读取已经序列化的文件
(2)反序列化和序列化时的对象要求所在的类名,包名一致
提升:
序列化和反序列化时可以保存单个对象也可以保存集合。
--------------------反射:
1.概念:在编译器编译期间不知道要编译哪一个类,可以通过反射探索该类中的信息
即用户只给定了要编译的类的路径,需要通过反射获取该类中的属性,
方法,构造方法
2.反射需要使用的类:
Class:表示类
Field:表示属性
Method:表示方法
Constructor:表示构造
注:所在包:java.lang.reflect
3.实现步骤:第一步先获取Class类的对象
(1)获取Class类的对象的方式:
//方式1:通过对象调用getClass()
User u=new User();//User是类名
Class cla=u.getClass();
//方式2:通过类名.class属性
Class cla=User.class;
//方式3:通过类的完整路径获取
Class cla=Class.forName("包名.类名");
(2)通过Class类的对象获取类中的属性
Field[] fs=cla.getDeclaredFields();
//获得普通方法
Method[] ms=cla.getDeclaredMethods();
//获得构造方法
Constructor[] cons=cla.getDeclaredConstructors();
(3)通过反射创建类的对象
<1>通过无参构造创建对象
Object obj=cla.newInstance();//cla表示Class的对象
<2>通过有参构造创建对象
//1.先获得指定的有参构造
Constructor con=cla.getConstructor(new Class[]{数据类型.class});
//2.通过该构造的对象创建所在类的对象
Object o=con.newInstance(new Object[]{属性的具体值});
(4)通过反射修改属性值
步骤:1.先获得Field类的对象
Field f=cla.getDeclaredField("属性名");//cla表示Class类的对象
步骤2:调用Field类中的方法
set(Object obj,Object val):
对引用数据类型赋值,参数1表示对象名,参数2表示属性值
get(Object obj):
获得引用数据类型的值,参数表示对象名
setXXX(对象名,属性值):对基本数据类型赋值
getXXX(对象名):对基本数据类型取值
setAccessible(true);//取消权限检查
(5)通过反射执行类中的方法
步骤1:先获取指定的方法
Method m=cla.getDeclaredMethod("方法名",new Class[]{});
//第二个参数表示方法的参数列表,对于无参方法,可以省略
步骤2:执行该方法
Object o=m.invoke(对象名,new Object[]{参数值});
//对于无参方法,invoke中第二个参数可以省略
注:通过反射给属性赋值或调用类中的方法,都需要传入该类的一个对象
复习:
1.序列化和反序列化:
序列化:
(1)给需要序列化的对象所在的类实现Serializable接口
(2)创建ObjectOutputStream 对象
并调用writeObject(Object obj);
(3)关流(逆序关闭)
反序列化:
(1)创建ObjectInputStream对象,调用readObject():Object obj;
(2)关流(逆序)
注:要求序列化和反序列化的对象要在相同包下
2.反射:在对类中的信息未知的情况下,
通过类的路径获得该类的属性,方法,构造方法
使用的类:
Class,Field,Method,Constructor
掌握的内容:
1.Class类的对象是反射的入口
(1)方式1:通过对象名调用getClass()方法
(2)方式2:通过类名调用class属性
(3)方式3:通过类的完整路径:Class.forName("包名.类名");
2.构造:通过构造创建对象
(1)调用无参构造;
cla.newInstance();//cla是Class类对象
(2)调用有参:
Constructor con=
cla.getConstructor(new Class[]{数据类型.class});
Object obj=
con.newInstance(new Object[]{具体参数值});
3.注:反射中执行属性或方法前先创建对象
调用属性,实现对属性的赋值和取值:
引用数据类型:
set(对象名,属性值);
get(对象名)
基本数据类型:
setXXX(对象名,属性值)
getXXX(对象名)
设置权限:setAccessible(true);
4.调用方法:
获得Method对象:getDeclaredMethod("方法名")
执行方法:invoke(Object obj,参数值的列表):Object obj;
-----------------------------------注解:
1.什么是注解:
用于修饰数据的数据,对类或方法进行描述,功能类似于注释
对比注释和注解:
相同点:用于对类中的信息进行描述
不同点:注释是给程序员看的,程序不会执行
注解是给程序看的,程序运行期间会执行注解信息
2. 定义格式:以@开头,示例:@Override
注解分类:
(1)内建注解(@Override)
(2)元注解:
对比:元数据:修饰数据的数据,即注解
元注解:修饰注解的注解,通常和自定义注解一起使用
(3)自定义注解:使用@interface实现
3.内建注解;
限定重写父类方法:@Override
标示已过时:@Deprecated
抑制编译器警告:@SuppressWarnings
注:可以修饰类,方法,语句
可以给该注解传值:
@SuppressWarnings(value="");//当为一个值时value可以省略
4.元注解和自定义注解:
(1)自己去开发框架
(2)提示项目档次
自定义注解的格式:
public @interface 注解名{
数据类型 变量名() default 默认值;
}
示例:
public @interface AnnoTest{
String name() default "";
int age() default 19;
}
注:(1)注解中的变量名后必须添加小括号
(2)当注解中的变量没有默认值时,必须在调用时给定
(3)变量给默认值时使用default关键字
练习:自定义注解,注解中保存要连接的数据库的类型值,定义一个方法,并读取该注解
根据注解值判断连接的数据库类型
mysql,oracle,sqlserver
获取注解信息:
(1)getAnnotation():Annotation[]
//得到所有修饰的注解
注:读取注解信息时,注解要求添加@Retention(RetentionPolicy.RUNTIME)修饰
(2)判断注解之间的关系:instanceof
(3)元注解:
<1>@Target(ElementType.枚举值)
设置被修饰注解修饰的元素,如方法或类等
<2>@Retention(RetentionPolicy.静态值)
设置被修饰注解是否可以通过反射读取
RetentionPolicy.RUNTIME;//指程序运行期间可以通过反射读取注解信息
----------------------线程:
1.线程和进程的区别:
进程:运行程序时,就会打开一个进程
线程:进程中的最小单位,一个进程中至少包含一个线程,
示例:
qq程序属于进程,同时和多人聊天属于线程
2.实现方式:
(1)继承Thread类,重写run(),调用start()方法启动线程
示例:
public class T1 extends Thread{
@Override
public void run(){
//需要让线程做的事情
}
}
//启动线程:
T1 t=new T1();
t.start();
注:<1>获得当前线程的名称:Thread.currentThread.getName();
<2>main方法执行时,其实也启动了一个线程
<3>多个线程执行时,线程的优先级更多的取决于电脑给它分配的优先级
所以多线程执行时,结果不唯一。
(2)实现Runnable接口
public class 实现类名 implements Runnable{}
//启动线程:注意:创建Thread类的对象,将实现类的对象作为参数传入
Thread t=new Thread(new 实现类名());
t.start();
3.线程的生命周期:
新生状态,可运行状态,阻塞状态(会暂停线程执行),死亡状态
可运行->阻塞的原因:
(1)io流阻塞(2)人为使线程睡眠 (3)线程锁
4.线程的调度
修改线程优先级:
线程对象.setPriority(优先级的值);
注:优先级的值1-10,默认5,值越大,优先级越高
线程调度方法:
sleep(毫秒数);//1秒=1000毫秒
注:sleep是静态方法,由Thread调用
复习:
(1)注解:
<1>什么是注解:修饰数据的数据(元数据)
<2>分类:
1.内建注解
2.元注解
3.自定义
<3>自定义注解:
1.@interface
2.定义属性:数据类型 属性名() default 默认值
3.当自定义注解中的属性没有默认值时,调用该注解时必须指定属性值
(2)线程:
<1>线程创建:
1.继承Thread
2.实现Runnable接口
<2>线程的启动:
1.继承方式时:
new 线程类(子类)对象
2.实现方式时:
new Thread(线程类的对象);
调用start()方法启动线程
将线程要做的事情定义在run()方法中
<3>线程生命周期:
新生状态,可运行状态,阻塞状态,死亡状态
<4>线程的调度方法
1.sleep():使线程进入睡眠状态
2.join():用于指定线程插队,插队的线程执行完成后,继续后续线程
3.yield():使线程进入暂停状态
对比: sleep() yield()
线程进入阻塞状态 进入暂停状态
休眠期间,其他线程等待 暂停期间,如果没有其他线程,立即启动自身线程
对于其他线程的机会是均等的 启动优先级相同或更高的线程
<5>线程同步:
(1)当两个或两个以上的线程访问同一资源时使用
(2)作用:线程同步后,只允许同一时间只能有一个线程访问资源
(3)实现方式:
<1>同步方法:
public synchronized 返回值类型 方法名(){}
<2>同步代码块
synchronized(同步对象){
//同步操作
}
(4)实现原理:当同步对象有线程访问时,给该资源上锁,当线程访问结束后解锁,
让另一线程访问。
<6>线程通信:
实例:生产者和消费者的关系
实现方法:
wait():void--Object 使线程处于等待状态
notify:唤醒等待的线程,
notifyAll():唤醒所有的线程
注:这三个方法要用在同步方法或同步代码块中。
-----------------------------------------网络编程(Socket编程)
本机地址:(1)本机ip地址(2)localhost(3)127.0.0.1(回还地址)
获取本机ip地址:ipconfig
测试网络是否连通:ping 目标ip
------------Socket
1. 也称为“套接字”,是网络传输过程中的媒介,用于保存发送方和接收方的数据
2.执行过程:
发送方:先定义发送的内容,然后将内容保存给socket,然后由socket进行发送
接收方:检测是否有数据发送过来,随时得待接收socket,接收完成后,获取
socket中的信息
3.实现过程:
(1)发送方:创建socket对象
//1.创建Socket对象
Socket socket=new Socket("接收方ip地址",端口号);
//2.得到输出流
OutputStream os=socket.getOutputStream();
//3.写入内容
os.write(String.getByte());//String 表示字符串变量
//4.关流
os.close();
socket.close();
(2)接收方;创建ServerSocket对象
//1.创建ServerSocket对象
ServerSocket server=new ServerSocket(端口号);
//2.获得Socket对象
Socket socket=server.accept();//执行到accept()时会暂停程序
//3.得到输入流
InputStream in=socket.getInputStream();
//4.调用方法获得数据
in.read(byte[] b);//会将读到的数据保存到b数组中
//String s=new String(byte[] b);//将字节数组转换成字符串
//5.关流
in.close();
socket.close();
server.close();
复习:
1. 网络编程:(socket--套接字)
作用:可以通过网络进行数据的传输,而不限定于某一个项目或某台电脑
2.客户端和服务器端(发送方和接收方)
服务器:(处理客户端发送的请求)
ServerSocket server=new ServerSocket(端口号);
Socket socket=server.accept();//暂停程序
通过socket获得输入输出流,获得流中信息,最后关流
客户端:
Socket s=new Socket("对方ip地址",端口号);//获得输入输出流,获得流中信息,最后关流
------------------------基于TCP协议进行数据传递(安全性高)
(1)客户端和服务器端互相发送字符串
<1>获得接收的字符串:(使用字符流)
InputStream in=socket.getInputStream();
BufferedReader br=new BufferedReader(new InputStreamReader(in));
String s=br.readLine();
<2>socket.shutdownOutput();//禁用此套接字中的输出流
如果发现客户端和服务器端程序未结束,也不能接收数据时,调用
(2)客户端和服务器端互相发送对象(使用的是序列化的知识):
//发送数据(序列化):
OutputStream out=socket.getOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(out);
oos.writeObject(Object obj);
//接收方(反序列化):
InputStream in=socket.getInputStream();
ObjectInputStream ois=new ObjectInputStream(in);
Object obj=ois.readObject();
注:传递对象时,该对象所在的类要实现Serializable接口
(3)如何实现多用户登录(多线程)
实现要点:服务器端始终处于运行状态,接收一个请求就启动一个线程
注:不要把创建ServerSocket对象的代码放在循环中。
-----------------------基于UDP协议的数据传递(安全性低)
使用的类:
DatagramPacket(数据包)
DatagramSocket(发送和接收数据)
实现思路:将要接收或发送的数据保存到DtagramPacket
然后使用DatagramSocket进行接收或发送
//1.发送方:
InetAddress ia=InetAddress.getByName("接收方ip地址");
DatagramPacket dp=new DatagramPacket(发送的字节数组,发送长度,ia,端口号);
//调用send()方法发送
DatagramSocket send=new DatagramSocket();
send.send(dp);
//2.接收方:
DatagramPacket dp=new DatagramPacket(接收的字节数组,数组长度);
DatagramSocket receive=new DatagramSocket("端口号");
//接收数据
receive.receive(dp);
//将接收的数据转换成字符串
String s=new String (dp.getData(),0,dp.getLength());
使用网络编程实现超市管理系统中的新增商品,查看商品列表,
根据编号查询单个商品信息,商品入库,商品出库。
提示:
服务器端保存商品信息和客户信息,以及验证等逻辑方法
客户端负责接收客户信息,将内容传递给服务器
socket(网络编程):
实现方式:(1)基于TCP协议(重点)(2)基于UDP协议
基于TCP:
用到的类:Socket(客户端),ServerSocket(服务器端)
(1)客户端:
Socket socket=new Socket("服务器的ip地址",端口号);
通过socket对象得到输入和输出流读写数据
(2)ServerSocket
ServerSocket server=new ServerSocket(端口号);
Socket socket=server.accept();//通过socket得到输入输出流
三个实现案例:
(1)实现字符串的传递
(2)实现对象的传递(序列化)-重点
(3)实现多用户的操作
注:传递对象时要求发送方和接收方对象所在的包名,类名都要相同
--------基于UDP:
DatagramSocket(发送和接收数据),DatagramPacket(保存或接收要传递的数据)
-----------------------------------------------------
保存数据的方式:
(1)单个变量(2)数组(3)对象(属性) (4)集合(对象集合)--优化版的数组
----永久化保存数据的方式:
(1)io流保存(字符串保存-->对象保存(序列化和反序列化))
(2)xml文件保存
*.xml xml类型的文件
优势:保存的内容结构清晰,易读。
-------------xml
(1)xml文件的定义:
格式良好的xml定义要求:
<1>必须有声明语句
<?xml version="1.0" encoding="UTF-8"?>
<2>有且只能有一个根元素(根标签)
<3>严格区分大小写
<4>属性值必须在双引号中(属性定义在开始标签)
<5>标签最好成对出现
<6>标签之间要正确嵌套
(2)xml文件的优势:
<1>永久性(持久化)保存数据<2>实现数据交互<3>数据配置(框架中使用)
(3)xml文件的格式:
作用:对当前的xml文件格式进行限定或描述,描述当前xml文件中单个标签,标签和标签
之间的关系。
实现方式:DTD验证,Schema验证
DTD验证代码:
<!DOCTYPE 根标签名[验证语句]>//定义在声明语句和根标签之间
? -- 0-1次
* -- 0-多次
+ -- 1-多次
验证语句:
1.标签验证:<!ELEMENT 标签名 (该标签中的内容)>
注:如果标签中是子标签时,写标签名,如果标签中写的是文本内容,写#PCDATA
定义DTD验证时,从根元素开始,直到文本内容结束。
2.属性验证:<!ATTLIST 标签名 属性名 属性类型 默认值>
作用:指定标签中的属性格式
注:默认值使用双引号引起来
xml文件中的注释:<!-- 注释 -->
外部dtd:只定义元素的格式
引用外部dtd:
<!DOCTYPE 根元素 SYSTEM "dtd文件名">
注:把dtd和文件放在同一目录下
--------------------------
(4)xml文件的解析(重点):
<1>常见解析方式:DOM,SAX,JDOM,DOM4J
<2>Dom解析使用的类以及接口:
Document 表示整个xml树
NodeList 节点集合
Node 节点对象(包含本节点以及节点的子内容)
Element 表示标签
<3>实现步骤:
//1.获得解析器工厂对象
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
//2.获得解析器:
DocumentBuilder builder=factory.newDocumentBuilder();
//3.解析文件
Document doc=builder.parse("src/school.xml");//parse("文件路径")
//getDocumentElement():Element得到根元素
//getChildNodes():NodeList得到子节点集合
//item(i):Node 获得NodeList中的每一个Node
//getLength():获得NodeList的长度
//getNodeName():获得节点名字
//getTextContent():获得文本内容
//获得标签中的属性:需要强转成Element类型
if(node对象.getNodeType==Node.ELEMENT_NODE){
Element ele=(Element)node对象;
ele.getAttribute("属性名")
}
-------------------------DOM4J解析:jar包(java中的压缩包)
用到的类:Document,Element,Attribute,Text
实现步骤:
//1.创建SAX对象
SAXReader reader=new SAXReader();
File file=new File("src/score.xml");
//2.调用read(File f)方法
Document doc=reader.read(file);
//3.得到根元素
Element root=doc.getRootElement();
elements();//得到子节点集合
getName();//得到节点名
attributeValue("属性名"));//得到节点属性名
getText();//得到标签中的文本
XML--文件类型(.txt,.doc等)
作用:1.保存数据(.txt,doc)--特点:格式化保存数据
2.是网络信息传递中的主要方式
3.配置文件(框架中)
掌握:
1.定义(知道如何保存数据)
2.解析xml
(1)方式:DOM(基础),SAX,JDOM,DOM4J(开发中使用)
(2)操作模式:xml文件的增删改查
dom和dom4j:
相同点:都使用到Document(树结构)对象
不同点:解析思路
注:dom解析使用org.w3c包下的类或接口
dom4j使用的是dom4j自己的jar包
----dom4j中对xml文件的增删改
步骤:
1.访问xml
2.修改xml内容
3.将修改后的内容保存到xml文件中
小结:
任何一种解析方式主要掌握对xml文件的增删改查
作业:将超市管理系统中商品的信息保存到xml文件中,进行数据的增删改查
--------------------------------------
复习:
1.java基础
变量定义,常量定义,语句结构(选择,循环,跳转语句),数组
2.java中面向对象
类,对象,属性,方法,构造方法,封装,继承多态,抽象类和接口
异常处理
3.java高级应用(使用底层类(工具类)):
<1>集合(List,Set,Map),<2>实用类(封装类,Math,Random,Date,Calendar),
<3>枚举类型(常量的集合),
<4>io流(字节流(FileInputStream,FileOutputStream)
和字符流(BufferedReader,BufferedWriter)
掌握程度:使io流文件和程序之间传递字符串
<5>io流的升级(传递对象)--序列化和反序列化
<6>反射:通过类的路径反向获取类中的属性或方法
线程:1.线程的创建2.线程的调度(sleep(),join(),yield())
3.同步线程 4.线程之间的通信
<7>注解(自定义注解,元注解,内建注解)
<8>网络编程(Socket编程)
1.客户端和服务器端传递字符串
2.客户端和服务器端传递对象
3.多线程和网络变成结合:实现多用户登陆
<9>XML文件
1.dtd验证 2.xml的定义 3.对xml文件的解析以及增删改查的操作
----------------jdbc连接数据库
搜索:myeclipse8.6在线注册
输入注册码:
myeclipse->windom->最后一个->myeclipse->subscription选项
->enter subscription
----为什么讲数据库
(1)存储量大(2)存储数据的性能好(3)充当服务器
----如何使用数据库
(1)如何创建数据库
(2)如何创建表空间(mysql是共用的一个表空间,在安装时已经创建完成)
(3)创建表
(4)添加数据,并对数据进行增删改查
(5)复杂查询(条件查询,排序,分组,分页,子查询,多表查询)
(6)常用的约束类型
(7)表中数据的备份
复习:mysql
1.数据库的安装和卸载
2.数据的基本操作
<1>创建表
create table 表名(
列名 数据类型 [约束条件],
列名 数据类型 [约束条件]
);
<2>对表中的数据进行增删改查
增加:
insert into 表名(列名) values(列值);
insert into 表名(列名) values(列值),(列值);
更新数据:
update 表名 set 列名=列值 where 限定条件
update 表名 set 列名=列值,列名=列值 where 限定条件
删除:
delete from 表名 where 限定条件
查询:
select 列名 from 表名;
注:当查询所有列时,列名位置使用*代替
------------------------------------------------
1.查询(普通查询,条件查询,分组查询,子查询,排序,多表查询)
select 列名
from 表名
where 限定条件 //多条件查询时,条件之间使用逻辑运算符(and,or,not)
order by 排序的列 desc/asc //desc表示降序,asc表示升序(默认)
Users
username 用户名
password 密码
age 年龄
sex 性别
//1.条件查询(where条件):年龄大于18的学生的名字
select username from Users where age>18
//2.条件查询:年龄大于18,性别是男生的学生的名字
select username from Users where age>18 and sex='男'
//3.(单列排序查询)根据年龄进行降序排序
select * from Users order by age desc
//4.非空查询:查询名字不为null的学生信息
select * from Users where username is not null;
//5.给列起别名查询:
语法:列名 as 别名 //起别名只是把虚拟表中的列名进行修改
//6.分页语句
语法: limit 开始的位置,显示的条数;//开始位置从0开始计算
开始位置=(页码-1)*显示的条数
小结:where ,order by ,limit出现的顺序:
where 限定条件
order by 排序的列 asc/desc
limit (页码-1)*显示的条数,显示条数
//7.多列排序
order by 列名1 asc/desc,列名2 asc/desc
执行原理:先按照列名1进行排序,当列值重复时按照列名2进行排序
//8.常量列:
概念:在虚拟表中添加额外的一列,同时也不会改变实体表中的列结构
语法:列值 as 列名
注:如果进行列值计算,是按行的方式计算数据
示例:
select *,java+mysql as 总分 from scores;
//9.去重查询(去除重复数据):
语法:distinct 列名 //去除该列中的重复数据
示例:
select distinct stuid from scores;
//10.模糊查询:like --添加在限定条件中
概念: 只查询出大概的数据范围
语法:列名 like 表达式 ;//表达式肯定是字符串
表达式的定义:
通配符:
% :0-多个字符
_(下划线):1个字符
//示例:查询姓张的学生信息:
select * from Users where username like '张%';
//查询姓张,两个字的学生信息
select * from Users where username like '张_';
//11.区间查询: //定义限定条件中
语法: 列名 between 开始值 and 结束值;
注:1.开始值<结束值
2.区间查询中边界值是包含开始值和结束值
等价于:列名>=开始值 and 列名<=结束值
示例://查询年龄在18-25之间
select * from Users
where age between 18 and 25;
等价于:
select * from Users
where age>=18 and age<=25;
//12.in查询(范围查询): //定义在限定条件中
语法:列名 in (列举的值);
注:列举的值使用逗号间隔
示例:查询在北京或上海的用户信息
select * from Users
where address='北京' or address='上海';
等价于:
select * from Users
where address in ('北京','上海');
//13.聚合函数:
最大值:max(列名),最小值:min(列名),平均值:avg(列名)
总和:sum(列名),总行数:count(列名)
注:因为总行数和列的名字无关,所以通常计算总行数时都使用count(*)
注:select count(distinct stuid) from scores;
补充:
实现分页效果:1.页码 2.显示的条数 3.总行数(count(*))
分页语句:limit (页码-1)*显示的条数,显示条数
总页数=总行数%显示的条数>0?总行数/显示条数+1:总行数/显示条数
(知识点:三目运算符---表达式?结果1:结果2)
//14.分组查询
(1).执行原理:根据被分组的列中的值进行分组,相同值的放在一组,
然后对每组值进行统计
(2).语法:
select 列名
from 表名
group by 被分组的列
注:如果查询语句中出现分组语句,则select 后面跟的列只能是
被分组的列以及聚合函数
//统计男女各多少人
select count(*),sex
from student
group by sex;
(3)多列分组
group by 列名1,列名2
执行过程:先按照列名1进行分组,然后按照列名2进行分组....
示例:
//查询每班男女的人数
select gname,count(*),sex
from Student
group by gname,sex;//gname表示班级名称
(4)分组后添加限定条件
语法:
group by 被分组的列
having 分组后的限定条件
//示例:查询人数大于15人的班级名称
//思路:先根据班级名称进行分组,并统计各班人数,完成后再限定人数>15
//所有人数大于15属于分组后的限定条件
select gname,count(*)
from student
group by gname
having count(*)>15
(5)单表查询的所有情况:
select 列名
from 表名
where 分组前的限定条件
group by 被分组的列
having 分组后的限定条件
order by 排序的列 asc/desc
limit 开始位置,显示条数;
注:
where 和having 的区别:
相同点:添加限定条件
不同点:(1)添加的时机不同,一个分组前,一个分组后
(2)where可以单独出现,having必须和group by 一起出现
反之,group by 不一定要和having一起出现
----------------------------------------------------约束条件:
1.添加时机:创建表时添加
2.create table 表名(
列名 数据类型 [约束条件]
);
3.约束条件的作用:为了保证保存到数据库中的数据的有效性
4.约束的分类:
(1)主键约束(primary key)
特点:主键列非空,唯一,通常情况下每张表都有一主键列
(2)非空约束(not null)
特点:不允许为null值
(3)唯一约束(unique)
特点:不允许重复
(4)自增长(auto_increment)
特点:数据自动增加,应用在数值列,而且主键列
(5)默认值(default)
特点:当用户不指定值的时候,自动填充默认值
注:使用开发工具添加默认值时,默认值两侧添加单引号
(6)外键约束(foreign key) --体现表与表之间的关系
外键列:存放了其他表中的主键列的值(即外来的主键值)
外键表:存放了外键列的表叫外键表,一张外键表中可以有多个外键列
外键名的命名:FK_当前表名_外键列名
复习:
mysql中的查询方式:
1.单表查询时完整语法:
select 列名
from 表名
where 分组前的限定条件
group by 分组的列
having 分组后的限定条件
order by 排序的列 asc/desc
limit 开始位置,显示条数;
注:(1).如果查询中有group by ,那么select后面跟的是被分组的列
或聚合函数
(2).having必须和group by一起出现
2.聚合函数:
sum(列名)-求和,avg(列名),max(列名),min(列名),count(列名)-行数
3.约束条件:(实现,作用)
目的:保证数据的准确性
分类:
(1)主键:primary key
效果:非空,唯一
(2)非空:not null
(3)唯一:unique
(4)自增长:auto_increment(设定在主键列,而且是int类型)
(5)外键:foreign key
作用:实现表与表之间的关系
-----------------------------
数据库:
(1)多表查询
使用场合:当查询的数据分布在多张表中时使用
分类:内连接(重点)、外连接(左外连和右外连)
特点:内连接会将两张表中有关系的数据显示出来,数据较为准确
外连接会将主表中的数据全部显示,次表数据匹配显示
语法:
内连接:
<1>
inner join on
select 列名
from 表1
inner join 表2 on 表1.列名=表2.列名
[inner join 表3 on 表1或表2.列名=表3.列名]
where 限定条件
group by ....
<2>使用where条件
select 列名 from 表1,表2 where 表1.列名=表2.列名 and 其他限定条件
注:在多表联查中,on或where后要添加表之间的关系,即表之间的主外键关系
外连接:
<1>左外连:
select 列名 from 主表
left join 次表 on 主表.列名=次表.列名
where ....
<2>右外连:
select 列名 from 次表
right join 主表 on 主表.列名=次表.列名
where ...
注:1.在外连接中,主表和次表不能随意换位置
2.主表数据全部显示,次表数据匹配显示,没有匹配到的使用null填充
(2)子查询:
实现思路:将select查询出来的虚拟表作为新表进行二次筛选
或者将select查询出来的结果作为其他查询语句的限定条件
示例:
//1.对虚拟表进行二次查询
select name from (
select e.*,basesalary from emoloyee e
left join department d on e.depid=d.depid
left join salary s on e.empid=s.empid
) newtable where basesalary is null;
//2.将查询的结果作为限定条件
-- 查询emoloyee中哪些用户是dept表中的所在部门
select * from emoloyee
where
depid in (select departmentid from dept)
-------------------------------
小结:
mysql数据库:
(1)数据库的创建
(2)数据库表的操作(增删改查)
(3)数据库的约束条件
(4)数据库的查询(条件查询,模糊查询,分组查询,子查询,多表查询
------------------JDBC
1.java和数据库建立连接
java and database connection
2.将java中的内存数据保存到数据库中,并通过数据库进行数据操作
使用场合:数据量较大时使用
java --翻译(jdbc驱动)-- mysql/oracle/sqlserver
3.连接步骤;
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获得连接
String url="jdbc:mysql://地址:3306/数据库名";
java.sql.Connection con=
DriverManager.getConnection(url,用户名,密码);
//4.得到状态通道,执行sql语句
//注:当执行增删改时,调用executeUpdate(sql)方法,返回受影响的行数
// 当执行查询时,调用executeQuery(sql)方法,返回ResultSet结果集
示例:
int rs=con.executeUpdate("insert into ....");
ResultSet rs=con.executeQuery("select ....");
while(rs.next()){//判断是否有下一个
//rs.getXXX(列下标或列名),下标从1开始,XXX表示数据类型
rs.getInt(1);rs.getInt("age");
}
//5.关闭资源(当进行查询操作时,需要关闭ResultSet)
if(rs!=null){rs.close();}//rs是ResultSet的对象
if(st!=null){st.close();}//st是Statement的对象
if(con!=null){con.close();} //con是Connection的对象
4.预状态通道:先编译sql语句再执行
特点:1.先编译sql语句
2.支持占位符(?)--占位符位置从1开始
示例:
//使用?进行占位
PreparedStatement pps=con.prepareStatement("select * from users where name=? and pass=?");
//对占位符进行赋值
pps.setString(1,"admin");
pps.setString(2,"'admin' or 1=1");
//执行sql,注:这里的executeQuery()方法没有参数
ResultSet rs=pps.executeQuery();
1.BaseDao(连接数据的库的通用类)
public class BaseDao{
//1.数据库连接的字符串
private static String URL;
private static String USERNAME;
private static String PASSWORD;
private static String DRIVER;
//2.数据库连接使用的对象
private Connection con;
private PrepareStatement pps;
private ResultSet rs;
static{//加载属性文件
InputStream in=
BaseDao.class.getClassLoader().getResourceAsStream("属性文件名");
Properties pro=new Properties();
pro.load(in);
URL=pro.getProperty("key").trim();
USERNAME=pro.getProperty("key").trim();
PASSWORD=pro.getProperty("key").trim();
DRIVER=pro.getProperty("key").trim();
Class.forName(DRIVER);//加载驱动
}
//3.获得连接的方法
private void getCon(){
con=DriverManager.getConnection(URL,USERNAME,PASSWORD);
}
//4.绑定参数的方法
private void bunld(String[] params){
if(params!=null&¶ms.length>0){
for(int i=0;i<params.length;i++){
pps.setString(i+1,params[i]);
}
}
}
//5.增删改的通用方法
public boolean update(String sql,String[] params){
getCon();
pps=con.prepareStatement(sql);
bunld(params);
int result= pps.executeUpdate();
if(result>0){
return true;
}
return false;
}
//6.查询的通用方法
public ResultSet quer(String sql,String[] params){
getCon();
pps=con.prepareStatement(sql);
bunld(params);
rs= pps.executeQuery();
return rs;
}
//7.关闭资源
public void closeAll(){
if(rs!=null){
rs.close();
}
if(pps!=null){
pps.close();
}
if(con!=null){
con.close();
}
}
}
2.分层(表现层,业务层,持久层(dao包))
实体类的定义格式:
类名=表名
属性名=列名
dao包下的接口命名规范:实体类名+Dao
4.测试代码:
方式1:debug调试
方式2:junit测试(测试框架)
步骤1:添加jar包:选中项目右键->build path->config buildpath
->libraries->add library->junit ->junit4
步骤2:使用@Test定义被测试方法
示例:
@Test
public void a(){
//代码
}
注:1.默认情况下测试所有加了@Test的方法,运行指定测试方法时,选中方法名即可
2.定义的测试方法要是无返回值的
1.事务管理:用于管理对数据表的修改操作进行最后的确认
mysql中事务管理是自动的,即自动提交事务
//con是Connection的对象,默认为true
取消事务自动提交:con.setAutoCommit(false);
事务手动提交:con.commit();
事务回滚:con.rollback();//回滚到增删改操作之前的数据
2.java中常用的设计模式:
(1)单例模式:
<1>懒汉式
public class 类名{
private 类名(){}//私有化构造方法
private static 类名 对象名;//定义对象变量
public static 类名 getInstance(){//提供一个外界可以访问到的方法返回对象
if(对象名==null){
对象名=new 类名();
}
return 对象名;
}
}
<2>饿汉式:
public class 类名{
private 类名(){}
private static 类名 对象名=new 类名();
public static 类名 getInstance(){
return 对象名;
}
}
(2)工厂模式:
<1>简单工厂模式<2>工厂方法模式<3>抽象工厂模式
(3)适配器模式:
类适配器和对象适配器(优点:可以同时传入不同的对象)
(4)策略模式
------算法:
冒泡:
for(int i=0;i<n-1;i++){
for(int j=0;j<n-1-i;j++){
if(数组名[j]>数组名[j+1]){//升序
int temp=数组名[j];
数组名[j]=数组名[j+1];
数组名[j+1]=temp;
}
}
}
1.算法:
冒泡排序,直接插入算法,
折半插入算法(二分插入算法),折半查找算法(二分查找算法)
注:两种二分算法的前提条件是数组已经是有序的
2.数据结构:数据保存时的方式
线性表:
特点:1.有且仅有一个开始节点和结束节点
2.有且仅有一个直接前驱节点和直接后驱节点
3.有序性和均匀性
体现:
1.顺序存储(比如:arrayList):
特点:和数组类似,通过下标记录内容,并访问数据
2.链式存储(比如:LinkedList)
特点:存储非连续的内容,逻辑地址和物理地址不同
链式存储同时保存内容与下一个内容的地址
3.栈(Stack):
特点:只有一个口用于数据的存入和取出
先进后出
4.顺序队列(以顺序结构保存队列信息):
特点:允许一端进值,一端出值,
先进先出
注:进队列时,队尾的值改变,出队列时,队头的值改变
静态分配存储空间
入队在队尾,出队在队首
队列为空,front = rear
队列为满,rear = 队列长度 – 1
队列非空非满, front < rear < 队列长度 – 1
5.链式队列(以链式方式存储队列)
动态分配存储空间
入队操作在队尾,出队操作在队头
入队时无队满问题
队列为空:front = rear
3.递归
概念:方法本身重复调用自己的过程称为递归
示例:阶乘:
0! =1
1!=1*1
4!= 4*3*2*1=4*3!
5!=5*4*3*2*1=5*4!
6! =6*5*4*3*2*1=6*5!
关键代码:
public int jiecheng(int num){
if(num==0){
return 1;
}else{
return num*jiecheng(num-1);
}
}
示例2:斐波那契数列(后续值是前两个值相加的和)
//生兔子
public int nums(int month){//传递月份
if(month<2){
return month<=0?0:1;
}
return nums(month-1)+nums(month-2);
}
--------------
内部类:
(1)内部类编译成字节码文件后的命名:外部类名$内部类名.class
示例:Outter$Inner.class
(2) 如果外部类需要访问内部类的内容时,直接创建内部类的对象,调用属性或方法
public clas Out{
public class inner{
public void a(){}
}
//外部类直接创建内部类的对象
public void b(){
inner in=new inner();
in.a();
}
}
(3)其他类调用内部类操作时,需要先创建内部类的对象
创建对象1:
外部类名 外部对象名=new 外部类名();
外部类名.内部类名 内部对象名=外部对象名.new 内部类名();
示例:
Outter out=new Outter();
Outter.Inner in=out.new Inner();
创建对象2:
外部类名.内部类名 内部对象名=new 外部类名().new 内部类名();
示例:
Outter.Inner in=new Outter().new Inner();
(4)方法内部类:
概念:定义在方法中的类
注:1.该方法中的类只能在当前方法中使用
2.如果内部类需要访问方法中的属性时,要求该属性必须是常量,即final修饰
3.如果调用内部类的方法,则只能在当前方法中创建内部类对象
(5)匿名内部类:在创建对象时,将该类中的未实现的方法进行实现
使用场合:方法体不通用时,或方法体用的次数少时
示例:
接口名 对象名=new 接口名(){
//接口中未实现的方法
}
---------------------------------------
1.正则表达式
作用:数据有效性的校验
表达式:/^正则表达式$/
符号:\s --空格,
\S--非空格,
\d--[0-9],
\D---0-9以外的内容,
\w ---[a-zA-Z0-9]
次数:{n}-- 匹配n次
{n,} --匹配n到多次
{n,m}-- 匹配n-m次
* ---匹配0-多次
+ --匹配1-多次
? -- 匹配0-1次
测试:
字符串对象.matches("正则表达式");
示例:
String reg="^\\w{5,}$";
System.out.println("adsf".matches(reg));
2.堆栈内存图
(1)栈中保存的是基本数据类型的值和引用数据类型的对象引用
示例:10,true,12.3,Users user
(2)堆中保存所有new出来的对象
(3)常量池:保存String常量和基本数据类型常量
(4)常量池和栈中的数据可以共享,堆中不可以,即保存到常量池中的内容只能有一份,
堆中可以有多份。
(5)
String s="abc";//这种方式的String保存在常量池中
String s=new String("abc");//这种String保存在堆中
所以比较字符串使用equals()比较内容
3.String,StringBuffer,StringBuilder
开发中使用:String,StringBuffer
面试中使用:StringBuffer,StringBuilder
相同点:保存字符串
不同点:
(1)String保存的是字符串常量,另外两个保存字符串变量
(2)StringBuffer 属于线程安全,StringBuilder 非线程安全
(3)使用场合:
数据少时使用String,多线程中StringBuffer,单线程使用StringBuilder
4.自动装箱和拆箱
Integer i=10;//装箱
int b=i;//拆箱
5.Date
java.sql.Date 用于和sql有关的日期
java.util.Date 平常使用的日期格式,并且常和格式化操作一起使用
6.java.math.BigDecimal
作用:用于保存位数比较大的数据
常用方法:
add(BigDecimal) 值相加
subtract(BigDecimal) 值相减
multiply(BigDecimal) 值相乘
divide(BigDecimal) 值相除
注:创建该类对象时,建议使用String类型的构造方法
7.类之间的关联
示例:
public class Users{
public String name;
public Grade grade;
}
public class Grade{
public String gname;
}
public class Test{
main{
Users u=new Users();
u.name="";
Grade g=new Grade();
g.gname="";
u.grade=g;
syso("名字:"+u.name);
syso("gname:"+u.grade.gname);
}
}
8.java中垃圾回收机制(gc机制)
(1)哪些属于垃圾?
当变量或对象没有其他引用时,被视为垃圾
(2)测试垃圾回收器:
java -verbosegc class文件名;
(3)如何进行垃圾回收:
new 类名();//产生一个垃圾
System.gc();//调用垃圾回收器
System.runFinalization();//强制结束运行,进行垃圾回收
(4)finalize()方法用于对最后垃圾对象进行回收的最后确认
由程序自动调用
面试题:对比final,finally,finalize三个的区别
final 声明常量的关键字
finally 异常中的关键字,始终执行的代码放在finally块中,try-catch-finally
finalize 是垃圾回收机制中的方法名,用于对回收对象的最后确认