程序是一系列有序指令的集合;
Java主要用于开发两类程序:
1)桌面应用程序
2)Internet应用程序
1,Java程序:三步走,编写--编译--运行;
2,使用记事本开发:
1)以.java为后缀名保存文件
2)使用javac命令编译.java文件,生成.class文件
3)使用java命令编译.class文件,输出结果
3,main()方法是java程序的执行的入口点;
4,\n是换行符,\t是制表符
5,包资源管理器:
1)用包阻止Java源文件,类似于文件夹
2)选择菜单“Window-show view-package explorer”打开
src目录:存放包和源文件
JRE系统库目录:存放程序运行必须的系统库文件
6,导航器:
1)类似于windows中的资源管理器
2)选择菜单:“window->show view-navigator”
bin目录:存放可执行的字节码文件
src目录:存放java源文件
7,public修饰的类的名称必须与Java源文件同名!
System.out.println()和System.out.print()区别就在于一个换行,使用换行符\n可以是两者达到相同的效果
8,Java数据类型:
数值类型:整型(byte,short,int ,long),实型(float ,double),
非数值类型:char ,String
9,计算剩余的,就是利用%取余运算符
10,自动类型转换规则:
规则1:如果一个操作数为double型,则整个表达式可提升为double型;
规则2:满足自动类型转换的条件:
两种类型要兼容:数值类型(整型和浮点型)互相兼容;
目标类型大于源类型: 例如:double 型大于 int 型;int可以转换成double,double不能转换成int;大可转成小,小不能转成大
10,优先级顺序:
算术运算符>关系运算符>逻辑运算符
运算符赋值运算符(=);
算术运算符(+、 – 、*、/、%);
关系运算符(>、<、>=、<=、 ==、 !=);
11,数据类型转换包括自动类型转换和强制类型转换
12,if选择结构:是根据条件判断之后再做处理
if(条件) {: //条件必须是布尔值,
//代码块} //只有一条语句时,建议不省略大括号
多重if结构:当需要满足多个条件时使用,并且使用逻辑运算符
运算符优先级顺序:!>算术运算符>比较运算符>&&>||
13,产生随机数(0~9)的方法如下: int random=(int)(Math.random()*10);
14,四位数分解获得百位:num/100%10
15,多重if选择结构中的最后一个else可以省略;
16,Java中的if选择结构,包括以下形式:
基本if选择结构:可以处理单一或组合条件的情况;
if-else选择结构:可以处理简单的条件分支情况;
多重if选择结构:可以处理分段的条件分支情况;
嵌套if选择结构:可以处理复杂的条件分支情况;
0,循环由循环条件和循环操作组成
1,使用while循环时:
1)分析是否存在重复操作:
2)使用while循环实现:
确定循环条件和循环操作
套用while语法写出代码
检查循环是否能够退出
while循环:如果条件不成立,则一次都不执行操作
2,在编写程序时,会出现错误,但不好发现和定位错误,方法如下:
1)通过代码阅读或者加输出语句查找程序错误
2)当程序结构越来越复杂时,需要专门的技术来发现和定位错误,就是“程序调试”
程序调试的主要方法:
设置断点,单步执行,观察变量(F5单步跳入,F6单步跳过)
3,do-while:
特点:先执行再判断,while后面的分号不可少,
无论条件对错与否,其至少执行一次循环操作,
4,实现整数反转(回文):
int val=12345;
int r_digit;
System.out.print(r_digit);
val=val/10;
5,循环次数固定的时候:for循环比while循环更简洁
6,Scanner s=new Scanner(System.in);
System.out.println("请输入商品编号:"); //两句标准语句之间要加入表示请求的语句
int input=s.nextInt();//注意与上一句的位置顺序,若写在上一句的上面,则不会有效果
7,continue的使用情况:
当循环条件不满足时(如for循环中),可利用到continue,结束本次循环,继续下次循环的判断
8,for循环:
for(参数初始化;条件判断;更新循环变量){}
9,加法表:
Scanner s=new Scanner(System.in);
System.out.println("请输入数字:");
int val=s.nextInt();
for(i=0,j=val;i<=val;i++,j--){
System.out.println(i+"+"+j+"="+(i+j));
}
s.close();
10,continue 作用:跳过循环体中剩余的语句而执行下一次循环;continue跳出本次循环,进入下一次循环
break语句作用:终止某个循环,程序跳转到循环块外的下一条语句;
使用场合:
break常用于switch结构和循环结构中
continue一般用于循环结构中
11,循环结构:
while,do-while,for循环
1,需要多次重复执行一个或多个任务的问题时,考虑使用循环来解决问题
2,无论哪一种循环结构,都有4个必不可少的部分,初始部分,循环条件,循环体,迭代部分
适用情况:
循环次数确定的情况,通常选用for循环
循环次数不确定的情况,通常选用while或do-while循环
12,数组何时使用?
当数据繁琐,不利于处理时,使用数组。
数组是一个变量,存储相同数据类型的一组数据。
声明一个变量就是在内存中划出一块合适的空间
声明一个数组就是在内存空间划出一串连续的空间
13,数组长度固定不变,避免数组越界
14,double和float的区别???
15,数组中的所有元素必须是相同类型。
16,使用数组的四步:
1,声明数组,int[] a
2,分配空间,a=new int[5]
3,赋值,a[0]=8
4,处理数据,a[0]=a[0]*8
17,数据类型[ ] 数组名 = new 数据类型[大小] ;
18,声明数组:
为节省时间:
方法一:
边声明边赋值:int []score={89,85,96};
或者int[] score=new int[]{89,79,96};
方法二:动态地从键盘录入信息并赋值
Scanner input=new Scanner(System.in);
for(int i=0;i<30;i++){
score[i]=input.nextInt();
}
数组是引用类型,数组名并不是数组元素的内容,而是一个引用地址,方法参数传递的是数组地址,根据这个地址可以找到内存中存放数组元素的连续存储区,通过“数组名[数组元素下标]”的方式来访问数组元素。由于数组名实际上是一个内存地址,如果一个方法的返回值类型是数组,方法体重返回结果时应使用“return 数组名”,而不能在数组名后加中括号,并且方法头定义中用“类型[]”指明方法的返回类型。
例如:
public class Array{
static String[] getArray(){//返回一个字符串型数组,方法的返回类型是数组类型
String[] array={"123","sdf","45gfd"};
retrun array;//返回的是数组名
}
static void printArray(String[] data){//注意参数是数组类型,因为要输出数组元素
for(int i=0;i<data.length;i++){
System.out.println(data[i]);
}
}
public static void main(String[] args){
String[] rtnArray=getArray();
printArray(rtnArray);
}
}
使用Scanner类时:import java.util.Scanner;
二重循环是一个循环体内又包含另一个完整的循环结构;
在二重循环中,外层循环变量变化一次,内层循环变量要从初始值到结束值变化一遍;
在二重循环中可以使用break、continue语句控制程序的执行
在二重循环中使用continue:
for(int i=0;i<classnum;i++){
for(int j=0;j<score.length;j++){
if(score[j]<0){
continue; //若执行continue则只执行到此,直接执行j++,不执行count++了
}
count++;
}
}
在二重循环中使用break:
for(int i=0;i<5;i++){
System.out.println("欢迎光临第"+(i+1)+"家店");
for(int j=0;j<3;j++){
System.out.println("要离开吗(y/n)?");
choice=s.nextLine();
if('y'==choice){
break; //执行break,跳出内层(for)循环,继续执行外层(for)循环语句;
}
System.out.println("买了一件衣服");
count++;
}
}
break:跳出本层循环,
continue:继续本层下一轮循环
for循环执行顺序:
for(1,参数初始化;2,条件判断;4,更新循环变量){
3,执行循环体;
}
将字符d插入字符数组arr中:
char[] arr={'a','b','c','e'};
char ch='m';
int index=arr.length; //保存新增字符插入位置
for(int i=0;i<arr.length;i++){ //比较元素得到插入位置
if(ch<arr[i]){
index=i;
break;
}
}
for(int j=arr.length;j>index;j--){ //index下标开始的数组元素后移一个位置
arr[j]=arr[j-1];
}
arr[index]=ch; //插入数据
打印等腰三角形,直角三角形,倒直角三角形:
等腰三角形设计时,需要借助空格来实现
int rows=0;
System.out.println("请输入三角形行数:");
Scanner s=new Scanner(System.in);
rows=s.nextInt();
for(int i=1;i<=rows;i++){
for(int j=1;j<=rows-i;j++){
System.out.print(" ");
}
for(int k=1;k<=rows*2-1;k++){
System.out.print("*");
}
System.out.print("\n");
}
直角三角形:
for(int i=1;i<=rows;i++){
for(int j=1;j<=i;j++){
System.out.print("*");
}
System.out.print(" ");
}
倒直角三角形:
for( int i =1 ;i<=rows;i++){
for(int j=1;j<=rows-i+1;j++){
System.out.print("*");
}
System.out.print("\n");
}
如下代码生成四位随机数:
int max = 9999;
int min = 1000;
cardNumber = (int)(Math.random()*(max-min)) +min;
注意equals函数的使用:
if (userName.equals(inputName) && password.equals(inputPassword))
Java中运算符有算术运算符、关系运算符和逻辑运算符等;
Java中的类型转换分自动类型转换和强制类型转换;
多重if和switch选择结构都可以用于多分支的情况,但使用场合不同;
while循环先判断再执行,do-while循环反之;
for循环适用于循环次数确定的情况;
break和continue都可以改变程序执行的流程,但含义不同,使用场合也不同;
类和对象:
当在类中声明成员变量时注意位置,在类里面(成员方法外面,也在主函数外面)声明成员变量:
import java.util.Scanner;
public class T{
Strin name;
int age;
public void show(){
Scanner input=new Scanner(System.in);
while(!"n".equals(name)){//除了字符n外的字符串等于name
if(age>=18 && age<=60){
System.out.println("20元");
}else{
System.out.println("免费"):
}
}
}
}
public class InitialVistor{
public static void main(String[[] args){
Scanner input=new Scanner();
Visitor v=new Visitor();
System.out.println("请输入姓名:");
v.name=input.next(); //注意是next即可
System.out.println("请输入年龄:");
v.age=input.nextInt();
v.show();
}
}
方法之间允许相互调用,不需要知道方法的具体实现,实现重用,提高效率 :
Student类的方法a( )调用Student类的方法b( ),直接调用:public void a( ) { b( ); //调用b( )}
Student类的方法a( )调用Teacher类的方法b( ),先创建类对象,然后使用“.”调用 :
public void a( ) { Teacher t = new Teacher( ); t.b( ); //调用Teacher类的b()}
return只有在方法类型不是void时才能使用;
return不能返回多个值:如return weight,height;//这是错误写法
方法不能嵌套定义(即方法里面定义方法)
不能在方法外部直接写程序逻辑代码!:
例如:
public class Student4 {
int age = 20;
if(age < 20) { //不能有这段代码
System.out.println("年龄不符合入学要求!"); //也不能有这段代码
}//也不能有这段代码
public void showInfo() {
return "我是一名学生";
}
}
变量声明的位置决定变量作用域;局部变量则只能用在声明它的范围内,成员变量则可以用于该类的方法或其他类的方法;
变量作用域确定可在程序中按变量名访问该变量的区域;
成员变量和局部变量的区别:
作用域不同:
局部变量的作用域仅限于定义它的方法;
成员变量的作用域在整个类内部都是可见的;
初始值不同:
Java会给成员变量一个初始值;
Java不会给局部变量赋予初始值;
在同一个方法中,不允许有同名局部变量;
在不同的方法中,可以有同名局部变量;
在同一个类中,成员变量和局部变量同名时,局部变量具有更高的优先级;
JavaDoc注释:使用/**开始和*/结束,用来注释类,属性和方法等
/**
* AccpSchool类 //描述信息
*@author JadeBird //@author:描述作者信息
*@version 1.0 2011/06/21 @version :描述版本信息
*/
例:
/** * ScoreCalc类 //类的JavaDoc注释
* @author 北大青鸟
* @version 2.0 2013/06/01
*/
public class ScoreCalc {
/** Java成绩 *///属性的JavaDoc注释
int java;
//...
/**
* 计算总成绩 //方法的JavaDoc注释
* @return total
*/
public int calcTotalScore() {
int total = java + c + db;
return total;
}
//...
}
1,定义类的方法必须包括以下三个部分:
方法的名称,方法返回值的类型,方法的主体,
2,类的方法调用,使用如下两种形式:
同一个类中的方法,直接使用“方法名()”调用;
不同类的方法,首先创建对象,再使用“对象名.方法名()”来调用;
3,在Java中,有成员变量和局部变量,它们的作用域各不相同;
4,JavaDoc注释以“/**”开头,以“*/”结尾;
面向对象思想:
类的方法实现某个特定的功能,其他类不需要知道它如何实现,调用方法就可以了,不用重复写代码
Java获取随机数的3种方法:
注意:Java中,对于带参数形式的非void类型方法,调用方法后,要记得对返回值进行处理
例:
public boolean searchName (int start,int end,String name) {
boolean find = false; // 是否找到标识
// 指定区间数组中,查找姓名
for(int i=start-1;i<end;i++) {
if(names[i].equals(name)) {
find=true;
break;
}}
return find; //注意返回值的处理
}
数组作为参数的方法:
public double calAvg( int[] scores ){
int sum=0;
double avg=0.0;
for(int i =0;i<scores.length;i++){
sum+=scores[i];
}
avg=(double)sum/scores.length;
return avg;
}
对象作为参数的方法:
利用面向对象思想将多个参数封装成对象,将对象作为参数,这是更好的实现方式。
例:在实现了增加一个学生姓名的基础上,增加学生的学号、年龄和成绩,并显示这些信息,如何实现?
方式一:设计带四个参数(学号、姓名、年龄、成绩)的方法。
方式二:将学生学号、姓名、年龄、成绩封装在学生对象中,设计方法,以学生对象作为参数
包命名规范:
包名由小写字母组成,不能以圆点开头或结尾;
包名之前最好加上唯一的前缀,通常使用组织倒置的网络域名;
包名后续部分依不同机构内部的规范不同而不同 ;
总结:
带参方法定义的一般形式:
<访问修饰符> 返回类型 <方法名>(<参数列表>) { //方法的主体}
形参是在定义方法时对参数的称呼;
实参是在调用方法时传递给方法的实际的值;
调用带参方法时要求实参与形参要匹配;
创建包使用关键字package;
导入包使用关键字import;
String类(字符串类)位移java.lang包中,
String类提供了length()方法,确定字符串的长度 :
System.out.print("请输入密码: ");
pwd=input.next();
if( pwd.length()>=6 ){ //计算长度
System.out.print("注册成功! ");
}else{
System.out.print("密码长度不能小于6位!");
}
String类提供了equals( )方法,比较存储在两个字符串对象的内容是否一致 :
System.out.print("请输入用户名: ");
uname=input.next();
System.out.print("请输入密码: ");
pwd=input.next();
if( uname.equals("TOM") && pwd.equals("1234567") ){ System.out.print("登录成功! ");
}else{
System.out.print("用户名或密码不匹配,登录失败!"); }
“==”和equals()有什么区别呢?
==:判断两个字符串在内存中的首地址,即判断是否是同一个字符串对象;
equals():检查组成字符串内容的字符是否完全一致;
字符串连接:
方法一:使用“+”
方法二:使用String类的concat()方法
字符串常用提取方法:
搜索第一个出现的字符ch(或字符串value):返回出现第一个匹配的位置 如果没有找到字符或字符串,则返回-1
public int indexOf(int ch)
public int indexOf(String value)
搜索最后一个出现的字符ch(或字符串value):返回出现第一个匹配的位置 如果没有找到字符或字符串,则返回-1
public int lastIndexOf(int ch)
public int lastIndexOf(String value)
------------------------------------------------
public String substring(int index):提取从位置索引开始的字符串部分
public String substring(int beginindex, int endindex):提取beginindex和endindex之间的字符串部分
//beginindex: 字符串的位置从0开始算;endindex: 字符串的位置从1开始算
public String trim():返回一个前后不含任何空格的调用字符串的副本
StringBuffer类:
StringBuffer:String增强版
对字符串频繁修改(如字符串连接)时,使用StringBuffer类可以大大提高程序执行效率;
StringBuffer声明:
StringBuffer sb = new StringBuffer();//创建空的StringBuffer对象
StringBuffer sb = new StringBuffer("aaa"); //创建一个变量存储字符串aaa
StringBuffer的使用:
sb.toString(); //转化为String类型
sb.append("**"); //追加字符串
sb.insert (1, "**"); //插入字符串,在1的位置插入
例:
StringBuffer sb = new StringBuffer("青春无悔");
int num=110;
StringBuffer sb1 = sb.append("我心永恒");
StringBuffer sb2 = sb1.append('啊');
System.out.println(sb2); //青春无悔我心永恒啊
StringBuffer sb3 = sb2.append(num);
System.out.println(sb3); //青春无悔我心永恒啊110,此处相当于sb3.toString();
例:
从后往前插入:
输入一串数字,从后往前每3位插入一个逗号:
public class insertString {
public static void main(String[] args){
System.out.println("请输入一串数字:");
Scanner s=new Scanner(System.in);
String input =s .next();
StringBuffer str=new StringBuffer(input); //关键语句
for(int i=str.length()-3;i>0;i=i-3){ //关键语句
//注意从后往前,获取长度
str.insert(i,",");
}
System.out.print(str);
}
}
价格的格式化输出:从小数点往前数3位插入一个逗号
public StringBuffer change(double d){
StringBuffer str=new StringBuffer(String.valueOf(d));
for(int i=str.indexOf(".")-3;i>0;i=i-3){
str.insert(i,',');
}
return str;}
总结:
String类提供了大量的操作字符串的方法:
获得字符串的长度:length();
比较字符串:equals();
连接字符串:concat();
提取字符串:substring();
搜索字符串:indexOf();
拆分字符串:split();
常用的StringBuffer类提供的方法:
转换成String类型:toString();
连接字符串:append();
插入字符串:insert()
大小写问题:
使用equalsIgnoreCase()方法:比较时不考虑大小写问题
使用toLowerCase()方法:变成小写
使用toUpperCase( )方法:变成大写
通过字符串长度确定数组:
例:输入一段字符串,确定要查找的字符,输出是否包含该字符
public class Count {
public int counter(String inputs,String word){
//注意此处数组利用 输入的字符串的长度来确定
String[] str=new String[inputs.length()];
int count=0;
for(int i=0;i<str.length;i++){
str[i]=inputs.substring(i,i+1);//注意此处i,i+1
}
for(int j=0;j<str.length;j++){
if(str[j].equals(word)){//注意equals的使用
count++;
}
}
return count;
}
添加元素:
for(int i = 0; i < dvd.name.length; i++){
if(dvd.name[i] == null){ //查询最后一个空位置插入
dvd.name[i]=input;
dvd.state[i]=1;//置新增的DVD可借状态
System.out.println("新增《"+input+"》成功!");
break;
}
}
删除元素:遍历数组,查找匹配信息,若找到,每个元素前移一位:
//遍历数组,查找匹配信息
for(int i = 0 ; i < dvd.name.length; i++){
//查找到,每个元素前移一位
if(dvd.name[i]!=null &&dvd.name[i].equalsIgnoreCase(name)&&dvd.state[i]==1){
int j=i;
while(dvd.name[j+1]!=null){
dvd.name[j]=dvd.name[j+1];
dvd.state[j]=dvd.state[j+1];
dvd.date[j]=dvd.date[j+1];
j++;
}
//最后一个不为空的元素置空
dvd.name[j]=null;
dvd.date[j]=null;
System.out.println("删除《"+input+"》成功!");
flag=true;//置位,表示删除成功
break;
}else if(dvd.name[i]!=null &&dvd.name[i].equalsIgnoreCase(name)&&dvd.state[i]==0){
System.out.println("《"+input+"》为借出状态,不能删除!");
flag=true;//置位
break;
}
}
不匹配:
if(dvd.name[i] == null){ //无匹配
System.out.println("没有找到匹配信息!");
break;
}
可利用类SimpleDateFormat对字符串进行日期格式化:
SimpleDateFormat sd=new SimpleDateFormat("yyyy-MM-dd");
17,使用switch结构:特点:条件为等值判断,条件为整形或字符型;
default的顺序可以改变,但通常放在末尾,也可以省略,
18,switch和多重if的结构
相同:都用来处理多分枝条件的结构;
不同:
switch:只能处理等值条件判断的情况,而且条件必须为整形或字符行;
多重if结构:没有限制,特别适合某个变量处于某个连续区间的情况;
18,处理输入的数字异常:
Scanner对象的hasNextInt()方法,可以判断用户从键盘输入的字符是否是合法的数字
Scanner input = new Scanner(System.in);
if (input.hasNextInt()) {
//
}else{
System.out.println("请输入正确的数字!");
}
20,JAVA面向对象的编程:
1,对象初始化:
1)可以先创建对象,再利用对象.属性名 进行初始化;
2)可以在创建对象的同时,进行初始化,就要用到构造方法:
访问修饰符 构造方法名(){ //初始化代码;} //可以有参也可无参;构造方法名要和类名相同,当没有构造方法时,系统提供默认的无参构造方法;若是输出会显示为空;
2,this关键字:是对一个对象的默认引用,是为了区分同名成员变量;
3,重载:方法名相同,参数项不同;与访问修饰符和返回值无关;
例:构造方法的重载:
public Constructor1(){ name="美美"; id=10002 ; age=20;}
public Constructor2( String name, int id ,int age){this.name=name; this. id= id ; this. age=age;}
4,可以直接通过类名来调用方法或访问成员变量:但要用static修饰;
static final String a="hhhhhh"; //使用final修饰的称为常量,其值固定不变;
static可以用来修饰属性,成员,代码块;
static 修饰和非static修饰的区别:
注意:在普通的方法里不能定义static变量;在构造(类)方法里可以定义,static不仅称为静态变量还成为类变量,只能在类里声明类变量或类方法(用static声明的方法)
5,封装:面向对象的三大特征之一,定义:将类的某些信息隐藏到类的内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问;
6,封装的步骤:
1,修改属性的可见性:设为private;
2,创建公有的getter和setter方法:用于属性的读写
3,在getter和setter方法中加入属性控制语句:对属性值的合法性进行判断;
添加getter和setter方法的快捷键:shift +alt+s +r;
this关键字的用法:
this.属性;
this.方法;
调用构造方法:this();//如果使用,此时必须是构造方法中的第一条语句
this.("name","性别",20);
7,在写类的有参构造方法之前,注意应该加上一个默认的空的构造函数,
8,继承:满足is-a形式 ,即xxx是一种xxxxx
子类访问父类成员:使用super关键字,super代表父类
1)子类访问父类属性:super.属性;
2)子类访问父类方法:super.方法();
3)子类访问父类构造方法:super.()/super.(name,age,id); //访问构造方法时必须写在子类构造方法里的第一句
9,子类不继承父类的所有资源:
1)private成员
2)子类与父类不在同包,使用默认访问权限的成员
3)构造方法
10,访问修饰符总结:
11,多重继承关系的初始化顺序:
父类属性-->父类构造方法-->子类属性-->子类构造方法
12,继承是代码重用的一种方式,将子类的方法和属性放到父类中;
13,构造方法不能被继承,所以也不能被重写,
14,方法重写的规则 :
方法名相同 ,参数列表相同, 返回值类型相同或者是其子类; 访问权限不能严于父类
15,方法重载与方法重写
16,super关键字访问父类成员:
super只能出现在子类的方法或构造方法中;
super调用构造方法时只能在第一句;
super不能访问父类的private成员;
11,抽象:
由abstract声明的是抽象方法或抽象类;类图中,斜体的文字都是抽象的;
抽象类不能被继承;
抽象方法没有方法体,
抽象方法必须在抽象类里,
抽象方法必须在子类中实现,除非子类是抽象类;
12,类要想不被继承,方法想不被重写,属性值希望不被修改,只需要使用final进行修饰即可;
13,多态:同一个引用类型,使用不同的实例而执行不同的操作;
14,使用多态的执行思路:
1,编写父类
2,编写子类,子类重写父类的方法; //多态的要素一
3,使用父类的类型,子类对象 //多态的要素二
向上转型:Pet pet=new Dog(); //自动类型转换
向下转型(强制类型转换):
Pet pet= new Dog("金毛","拉布拉多");
Dog dog=(Dog)pet;
Penguin pen=(Penguin)pet; //会报错,必须转换为父类指向的真实子类类型
实现多态的两种形式:
使用父类作为方法形参实现多态;
使用父类作为方法返回值实现多态;
15,多态中,父类引用(即父类对象)不能调用子类特有的方法;
16,instanceof 运算符:
语法: 对象 instatnceof 类或接口
instanceof常和强制类型转换结合使用;
例:public void play(Pet pet){
if(pet instanceof Dog){ //如果传入的是狗狗
Dog dog=(Dog)pet;
dog.run();
}else if(pet instanceof Penguin){
Penguin png=(Penguin)pet;
png.swimming();
}
}
15,小结:
多态可以减少代码量,提高代码的可维护性和可扩展性;
向上转型:子类转换为父类,自动进行类型转换;
向下转型:父类转化为子类,结合instanceof运算符进行强制类型转换;
16,接口:
特性:
接口中的方法都是抽象方法,声明时即使没加abstract,接口也会自动加上的;
一个类可以实现多个接口,但非抽象类必须实现接口的所有方法;
接口没有构造方法;
接口不能被实例化; //常作为类型使用;
实现类必须实现接口中的所有方法;
实现类可以实现多个接口 ;//java中的多继承
接口中的变量都睡觉静态常量;
例:接口的使用:
编写接口:
public interface UsbInterface{
void service(); //usb接口提供服务;
}
实现接口:
public class UDisk implements UsbInterface{
public void service(){
System.out.println("连接usb,传输数据");
}
}
使用接口:
UsbInterface disk=new UDisk(); //用接口实现多态;
disk.service();
接口是一种能力,体现在接口的方法上;
面向接口编程:
程序设计时,关心实现类有何能力,而不关心实现细节;面向接口的约定,而不考虑接口的实现;
17,继承是:is-a的关系,是一个,,,,,
接口是:has-a 的关系,有一个,,,,,
18,一个类可以实现多个接口,中间用逗号分隔;定义接口的时候,里边方法先不用实现,通过类去实现;
19,如何理解接口是一种能力:
接口有比抽象类更好的特性:
1,接口可以被多继承,
2,设计和实现完全分离;
3,更自然的使用多态;
4,更容易搭建程序框架;
5,更容易更换实现;
抽象类利于代码复用,接口利于代码维护;
20,JAVA中为什么用get和set方法?
由于类中的一些属性有时访问权限是private的,即不能被其他的类随意进行访问,所以需要在类内使用get和set方法来方便其他类来访问,通常将方法名设置为get+字段名或set+字段名;
21,接口的访问修饰符不能是private,static,final,synchronized,native等,因为接口就是用来其他类去实现的;
22,C#中的接口定义:
格式:访问修饰符 interface 接口名:父接口名1,父接口名2,,,{
属性定义;
方法定义;
}
class 类名:父接口名,接口名1,接口名2,,,,{ ,,, }
23,java接口 和 C# 接口对比:
24,hasNextInt():判断输入的字符是否是整数;
25,System.exit(0); //正常退出
System.exit(1); //非正常退出 但两者都是退出;
26,java中为什么要使用get和set方法?
由于有些类的的属性生命为 private了,即不想被其他类随意进行访问,所以需要使用get和set方法来帮助其他类来访问;
通常方法的命名规则是get+字段名或set+字段名;
30,异常:指程序中发生的不正常事件,它会中断程序的正常运行;
31,java用来处理错误的就是利用 异常处理机制
32,java的异常处理是通过5个关键字来实现的:try, catch ,finally ,throw ,throws;
捕获异常:
try(执行可能产生异常的代码)
catch(捕获异常)
finally (无论是否发生异常总能被执行)
声明异常:throws ,声明方法可能抛出的异常;
抛出异常:throw,手动抛出异常;
33,使用try-catch块捕获异常的三种情况:
第一种情况:正常的
public void method(){
try {
//代码段 (此处不会产生异常)
}catch(异常类型 ex){
//对异常进行处理的代码段
}
//代码段
}
异常是一种特殊的对象,类型为java.lang.Exception或其子类
第二种情况:出现异常
public void method(){
try{
//代码段1
//产生异常的代码段2
//代码段3
}catch(异常类型 ex){
//对异常进行处理的代码段4
}
//代码段5
}
执行顺序:try(发生异常)-->产生异常对象-->和catch进行类型匹配-->若匹配则继续执行->代码段5;代码段3并不会执行;
第三种情况:异常类型不匹配:
public void method(){
try{
//代码段1
//产生异常的代码段2
//代码段3
}catch(异常类型 ex){
//对异常进行处理的代码段4
}
//代码段5
}
执行顺序:同第二种情况,只是和catch里的异常类型不匹配时,程序直接中断运行;代码段3和代码段5都不执行;
34,printStackTrace的堆栈跟踪功能,显示了程序运行到当前类的执行流程;
第一行的蓝体字代表:异常类型;
最后一行的蓝体字代表:异常出现在Test3.java中的第15行处的main()方法中;
异常对象的常用方法:
常见的异常类型:
34,在try-catch块的后面加finally:
1,是否发生异常都执行finally
try->catch->finally 或者 try-->finally
2,唯一不执行finally的情况:
当程序中断执行(catch处异常类型不匹配时)的时候
35,存在return的try-catch-finally块:
public void method(){
try{
//代码段1
//产生异常的代码段2
}catch(异常类型 ex){
//对异常进行处理的代码段3
return;
}finally{
//代码段4;
}
}
执行顺序:try(发生异常)-->产生异常对象,和catch进行匹配-->匹配则进入catch执行异常处理代码,不执行return-->执行finally-->最后执行return 退出方法;
try块中存在return的情况与此类似;
36,引发多重catch块:
1,排列catch语句的顺序,先子类后父类
2,发生异常时逐个按顺序匹配;
3,只执行第一个与异常类型匹配的catch语句;
假设有catch1,catch2,catch3
try(发生异常)-->产生异常对象-->和catch的异常类型进行对比-->与catch1不匹配-->则与catch进行对比-->匹配则进入执行代码-->直接继续执行try-catch后边的代码,不执行catch3了;
面试题:
1,try-catch中存在return语句,是否还执行finally块,若执行,说出顺序;
2,try-catch-finally中,finally唯一不执行的情况是什么?
37,如果在一个方法体 中抛出了异常,如何通知调用者呢?
public class Test7{
public static void divide() throws Exception{ //声明异常,多个异常用逗号分开;
//可能出现的异常代码;
}
public static void main(String[] args){
try{ //方式1:调用者处理异常;
divide();
}catch(Exception ex){
ex.printStackTrace();
}
}
public static void main(String[] args) throws Exception{ //方式2:调用者继续声明异常
divide();
} //main 方法声明的异常由java虚拟机处理
}
26,除了系统自动抛出异常外,有些问题需要手动抛出异常:
publi void setSex(String sex) throws Exception{
if("男"equals(sex) || "女".equals(sex)){
this.sex=sex;
}else{
throw new Exception("性别必须是\"+"男\"+"或\女"); //抛出异常;
}
}
27,throw和throws的区别:
throw:是抛出异常;通常写在方法里是手动抛出(若输入错误出现的提示)异常,
throws:是在(可能出现异常的)方法头部声明异常;
ex.printStackTrace(),通常写在catch块里面;
28,异常的分类:
Throwable:是Error类和Exception的父类;
Exception:是java程序抛出和处理的非严重错误;
Exception分为CheckedException和RuntimeException;CheckedException包括SQLException ,ClassNotFoundException等
Error:是仅靠程序本身无法恢复的严重错误;
RuntimeException:运行时异常,不需要程序必须作出处理;
Exception类中除了RuntimeException类异常外的如SQLException,ClassNotFoundExcepiton等这类的Checked异常都必须进行处理;
28,面试题:
说出常见的五个运行时异常;
throw和throws的区别?
29,开源日志记录工具:
实现以文件的形式记录异常信息,程序运行的关键步骤;
开源日志记录工具:log4j;
日志:主要用来记录系统运行中一些重要操作信息;
日志分类:SQL日志,异常日志,业务日志;
使用log4j记录日志的步骤:
1,在项目中加入log4j的jar文件;
2,创建log4j的properties文件;
3,配置日志信息;
4,使用log4j记录日志信息;
28,集合框架:
如果并不知道程序运行时会需要多少对象或需要更复杂方式存储对象---可以使用java集合框架;
java集合框架提供了一套性能优良的接口和类,它们位于java.util包中;
1,接口:Collection 接口和Map接口
Collection 接口包括List接口和Set接口,
2,具体类:
List接口包括的实现类:ArrayList,LinkedList ;
Set接口包括的实现类:HashSet , TreeSet ; (常用的是HashSet)
Map接口包括实现类:HashMap , TreeMap ; (常用的HashMap)
3,算法:Collections :提供了对集合进行排序,遍历等多种算法实现;
区别:
Collection 接口存储一组 不唯一,无序的对象;
List接口存储一组不唯一,有序(插入顺序)的对象;导包import java.util.List和import java.util.ArrayList
Set接口存储一组唯一,无序的对象;
Map 接口存储一组键值对象,提供key到value的映射; 导包import java.util.Map和import java.util.HashMap;
List接口的实现类:
ArrayList:实现了长度可变的数组,在内存中分配连续的空间。遍历元素和随机访问元素的效率比较高;
LinkedList :采用链表存储方式。插入,删除元素时效率比较高(适用于在任何位置进行插入删除);
List接口常用的方法:
例:
//创建四个狗狗对象
List dogs=new ArrayList();
dogs.add(ououDog);
dogs.add(meimeiDog);
dogs.add(2 , yayaDog); //添加元素到指定位置
dogs.remove(meimeiDog); //移除元素
System.out.println("共有"+dogs.size()+"只狗狗,分别是:"); //输出数量
for(int i=0;i<dogs.size();i++){
Dog dog=(Dog)dogs.get(i); //逐个获取元素; 注意此处的get()方法要用类型转换,
}
if(dogs.contains(meimeiDog)){ //判断是否包含指定元素 用contains()
//代码段
}
30,插入,删除操作频繁时可以使用LinkedList来提高效率;
LinkedList集合类的特殊方法:
注意:在获取列表中的第一个或最后一个元素时,要注意类型转换:
例:
LinkedList dog=new LinkedList(); //创建集合并存储各个对象;
dogs.add(yayaDog);
dogs.addFirst(meimeiDog);
dogs.addLast(ououDog);
Dog dogFirst=(Dog)dogs.getFirst(); //获取第一条狗狗信息
System.out.println("第一条狗狗的姓名是:"+dogFirst.getName());
dogs.removeFirst(); //删除第一个元素并返回列表中的第一个元素
Map接口常用方法:
使用get(Object key)由键来返回相关联的值时,注意类型转换
例:使用HashMap存储元素:
Map countries=new HashMap(); //使用Hashmap存储多组键值对
countries.put("US","美国");
countries.put("RU","俄罗斯");
String countries =(String)countries.get("US"); //获取指定元素的值,注意类型转换;
System.out.println("Map*有"+countries.size()+"组数据"); //获取元素的个数
countries.remove("US"); //传入的是键
System.out.println("Map中包含US的key吗?"+countries.containsKey("US")); //判断是否包含此元素
System.out.println(countries.keySet()); //显示键集
System.out.println(countries.values()); //显示值集
System.out.println(countries); //显示键值对集
开发过程中,最好使用ArrayList和HashMap;
30,集合类对比:
Vector 和 ArrayList 的异同:
Vector类也是可以实现动态数组的,但是设计涉及多线程时使用vector比较好;
实现原理,功能相同,可以互用;
主要区别:
1,Vector线程安全,ArrayList重速度轻安全,线程非安全;,
2,长度需增长时,Vector 增长一倍,ArrayList增长50%;
HashTable 和 HashMap的异同:
1,实现原理,功能相同,可以互用;
2,主要区别:
HashTable继承Dictionary 类,HashMap 实现Map接口;
HashTable 线程安全,HashMap线程非安全;
HashTable允许null值,HashMap不允许null值;
30,如何遍历Map集合?
方式一:使用迭代器Iterator进行遍历,需要导包import java.util.Iterator;import java.util.Set;
1)获取Iterator:Collection的iterate()方法;
2)Iterator的方法:
boolean hasNext():判断是否存在另一个可访问的元素;
Object next():返回要访问的下一个元素;
方式二:增强型for:
迭代器Iterator遍历Map集合:
Set keys=Map对象.keySet(); //取出所有key的集合;
Iterator it=keys.iterator(); //获取Iterator对象
while(it.hasNext()){
String key=(String)it.next(); //取出key
类名 类的对象=(类名)Map对象.get(key); //根据key取出对应的值
System.out.println(key+"\t"+类的对象.getStrain()); //此处getStrain()方法为获取品种
}
两者同样可以遍历其他类集合,但通常使用增加型for循环;
例:
Set keys=penguin.keySet(); //取出key的所有集合
Iterator it=keys.iterator(); //获取iterator对象
while(it.hasNext()){
String key=(String)it.next(); //取出key
Penguin penguin=(Penguin)map.get(key); //根据key取出对应的值
System.out.println(key+"\t"+penguin.getSex());
}
增强型for:
for(元素类型t 元素变量x :数组或集合对象){
引用了x的java语句;
}
31,如何解决List的get(int index)方法获取元素,Map的get(Object key)方法获取元素,Iterator的next()方法获取元素时出现的强制类型转换的异常呢?使用泛型解决
例:
创建ArrayList 集合对象并存储狗狗
List<Dog> dogs=new ArrayList<Dog>; //标记元素类型
dogs.add(dog1);
......
//dogs.add("hello");//类型不符,出现编译错误;
Dog dog=dogs.get(2); //显示第三个元素的信息
for (Dog dog:dogs){ //使用foreach遍历dogs对象 这两句不用强制类型转换
}
泛型集合:
例:
第一行标记键-值类型,
Set 和Iterator两行标记键类型;
while循环体和for循环体都不用强制类型转换了;
31,集合框架创建对象格式:
List arr=new ArrayList(); //创建ArrayList集合对象;
LiskedList dogs=new LiskedList(); //创建链表集合对象;
Map countries=new HashMap(); //创建Map集合对象
32,JDBC:是java数据库连接技术的简称,提供连接各种常用数据库的能力;
JDBC的工作原理:
1,JDBC API:
提供者:SUN公司;
内容:供程序员调用的接口和类,集成在java.sql和javax.sql包中;如:DriverManager类,connection接口,statement接口,resultset接口,
主要功能:与数据库建立连接,执行SQL语句,处理结果;
DriverManager:依据数据库的不同,管理jdbc驱动;
connection:负责连接数据库,并传送数据;
statement:由connection产生,执行SQL语句;
resultset:保存statement执行后产生的 查询结果;
2,DriverManager:
提供者:SUN公司;
作用:管理各种不同的jdbc驱动;
3,JDBC驱动:
提供者:数据库厂商
作用:负责连接各种不同的数据库;
33,JDBC的工作模板:
try{
Class.forName(JDBC驱动类); //加载jdbc驱动;
} 。。。。。。
try{
Connection con=DriverManager.getConnection(URL , 数据库用户名,密码); //与数据库建立连接
Statement st=con.createStatement(); //发送SQL语句,
ResultSet rs=st.executeQuery("SELECT a, b,c FROM Table1 "); //得到返回结果
while(rs.next()){ //next()返回要访问的下一个元素;
int x=rs.getInt(a); //处理返回结果
float f=rs.getfloat(c); //处理返回结果
String s=rs.getString(b); //处理返回结果
}
rs.close(); //释放资源
st.close(); //释放资源
con.close(); //释放资源 释放资源的顺序是从下向上;
}
Statement常用方法:
ResultSet常用方法:
在jdbc中进行SQL语句注入时,会出现隐患(使用相似的用户名或密码也能实现登陆),使用preparedstatement接口来解决这种隐患;
preparedStatement接口继承自statement接口,但比statement更灵活,更安全,更有效率;
使用preparedstatement进行更新数据库:
1,先声明preparedstatement变量pstmt;
2,使用不同与以往的带有带有占位符的SQL语句sql;;
3,创建preparedstatement对象spstmt;
4,执行sql语句:pstmt.executUpdate();
实现思路:
1,创建对象;
2,使用setXXX方法给占位符赋值;
3,调用execute();
ResultSet中的方法getXXX()方法在使用时,参数可谓列名或列号来标志列;
PrepareStatement比statement提高了代码的可读性,可维护性,安全性等性能;
数据访问层:
34,分层开发:
1,持久化:
定义:将程序中的数据在瞬时状态和持久状态转化的机制;
2,持久化的实现方式:
数据库,普通文件,XML文件;
3,持久化的主要操作:读取,查询,删除,修改,保存;
35,DAO:Data Access Object(数据存取对象)
DAO:位于业务逻辑和持久化数据之间;实现对持久化数据的访问;
DAO扮演转换器的角色,将实体类转换成数据库记录;
DAO模式的作用:
1,隔离业务逻辑代码和数据访问代码;
2,隔离不同数据库的实现;
DAO模式的组成部分:
DAO接口,DAO实现类,实体类,数据库连接和关闭工具类;数据库连接和关闭类是为了代码复用;
DAO模式的实际应用:
定义一个接口PetDao:
public interface PetDao{
int save(Pet pet);
int del(Pet pet);
}
定义PetDao接口的实现类:
public class PetDaoSql implements PetDao{
public int save(Pet pet){..............}
public int del(Pet pet){}
}
定义实现类的方法update();
public int update(Pet pet){
String driver="com......";
String url="";
String sql="update pet set status=0 where id=?";
pstmt=conn.preparestatement(sql);
pstmt.setInt(1,pet.getId());
result=pstmt.executeUpdate();
finally{ ........
if(null!=pstmt) pstmt.close();
if(null!=conn)conn.close();
}
}
各个方法中都有数据库的建立和关闭,如何解决代码重复问题?如果更换了额数据库,各个代码都要修改;通过使用BaseDao,将数据库的建立和关闭操作都放到一个专门的类中BaseDao;使其他的类继承BaseDao类;
数据库工具类BaseDao: 打开连接和关闭连接
public class BaseDao{
private static String url="jdbc...........";
private static String driver="com..............";
private static userName="Bob";
private static password="bob";
Connection conn=null;
public Connection getConnection(){ //获取数据库连接
if(conn ==null){ //获取连接并捕获异常
try{
Class.forName();
conn=DriverManager.getConncetion(url , userName, password);
}catch(Exception e){
e.printStackTrace(); //异常处理
}
}
return conn;
}
public void closeAll(Connection conn,Statement stmt , ResultSet rs){ //关闭数据库连接
if(rs != null){ rs.close();} //或者是添加异常:if(rs != null){ try{ rsl.close();}catch(Exception e){ e.printStackTrace();}}
if(stmt != null){stmt.close();} //或者是添加异常,同上
if(conn != null){stmt.close();} //或者是添加异常,同上
}
}
数据库工具类BaseDao:通用的增删改方法:
public int executeUpdate(String preparedSql , Object[] param){
PreparedStatement pstmt=null;
int num=0;
conn=getConnection();
try{
pstmt=conn.prepareStatement(preparedSql);
if(param != null){
for(int i=0;i<param.length;i++){
pstmt.setObject(i+1,param[i]); //为预编译sql设置参数
}
}
num=pstmt.executeUpdate();
}catch(Exception e){
e.printStackTrace();
}finally{
closeAll(conn, pstmt,null);
}
return num;
}
分层开发方法:一种化大为小,分而治之的软件开发方法;
分层的特点 :每一层都有自己的职责 ;上一层不用关心下一层的实现细节,上一层通过下一层提供的对外接口来使用其功能 ;上一层调用下一层的功能,下一层不能调用上一层功能 ;
分层开发的好处: 各层专注于自己功能的实现,便于提高质量; 便于分工协作,提高开发效率 ;便于代码复用 ;便于程序扩展;
不同层之间通过实体类传输数据;
分层原则:
封装原则:每个层次向外公开接口,但是隐藏内部细节;
顺序访问原则:下层为上层服务,但不使用上层服务;
36,FILE I/O:
文件:是相关记录或放在一起的数据的集合;
文件一般存储在:光盘,内存,文件夹内;
JAVA程序如何访问文件属性:通过java.io.File类;
File类访问文件属性:通过创建文件对象(File file=new File(String pathName);),然后操作文件或目录的属性(路径,权限, 日期等); String pathName如:"c:/test.txt" 或"c:\\test.txt"
File类的常用方法:
如何读写文件:通过流的方式:
流:是指一连串流动的字符,是以先进先出的方式发送信息的通道;
JAVA流的分类:
按流向区分:
输出流:以OutputStream和Writer做基类;
输入流:以InputStream和Reader做基类;
输入输出流是相对于计算机内存来说的;
按照处理的数据单元划分:
字节流:字节输入流:InputStream基类;字节输出流:OutputStream基类;
字符流:字符输入流Reader基类;字符输出流Writer基类;
字节流是8位通用字节流,字符流是16位Unicode字符流;
这些基类是抽象类,使用时,用的 是他们的子类;
文本文件的读写:
用FileInputStream和FileOutputStream,BufferedReader和BufferedWriter读写文本文件;
用DataInputStream和DataOutputStream读写二进制文件;
1,使用FileInputStream读取文本文件:
import java.io.IOExcepiton;
import java.io.FileInputStream; //引入相关类
FileInputStream fis=new FileInputStream("c\\test.txt"); //构造文件输入流 ,读取test.txt文件
fis.available();
fis.read(); //读取文本文件数据
fis.close(); //关闭流
InputStream类的常用方法:
int read();
int read(byte[] b);
int read(byte[]b, int off,int len);
void close();
int available();
子类FileInputStream常用的构造方法:
FileInputStream(File file);
FileInputStream(String name);
2,使用FileOutputStream写文本文件:
import java.io.IOException;
import java.io.FileOutputStream; //引入相关类
FileOutputStream fos=new FileOutputStream("c\\test.txt"); //构造文件输出流,将数据写到test.txt中
String str="好好学习";
byte[] words=str.getBytes();
fos.write(words,0,words.length); //写入文件
fos.close();
OutputStream常用方法:
void write(int c);
void write(byte[] buf);
void write(byte[] buf,int off ,int len);
void close();
子类FileOutputStream常用的构造方法:
FileOutputStream(File file);
FileOutputStream(String name); //将数据写到name处
FileOutputStream(String name,boolean append); //将数据写到name处;
前两种构造方法,在向文件中写数据时,会覆盖原有数据;
创建FileOutputStream实例时,如果相应文件不存在,则会自动创建一个空文件;
复制文本文件:
使用FileReader读取文件:
1,引入相关类文件:import 。。。。
2,创建FileReader对象:fr=new FileReader("D:/.....");
3,读取文本文件数据:length=fr.read();
4,关闭相关流对象:fr.close();
使用BufferedReader和FileReader读取文本文件能够提高字符流读取文件的效率,BufferedReader类是Reader的子类,带有缓冲区,又特有的按行读取的方法readLine();
BufferedReader读取文件步骤:
1,引入相关类;import java.io.Reader ,BufferedReader ,IOException
2,构造BufferedReader对象; FileReader fr=new FileReader("C:/test.txt"); BufferedReader br=new BufferedReader(fr);
3,调用readLine()方法读取文件;br.readLine(); null是readLine()的返回值,while( (br.readLine()) !=null)
4,关闭流对象;br.close(); fr.close();
Reader类常用方法:
int read();
int read (byte[] c)
read(char[] c, int off ,int length);
void close();
子类BufferedReader常用构造方法:
BufferedReader(Reader in); //注意参数是Reader类型的,确切的说是FileReader类型的
子类BufferedReader特有的构造方法:
readLine();
使用FileWriter写文件:
import java.io.Reader;
import java.io.FileWriter;
import java.io.IOException; //引入相关类
FileWriter fw=null;
try{
fw=new FileWriter("D:/test.txt"); //创建FileWriter对象
fw.write("你好"); //写入信息
fw.flush(); //刷新缓冲区;
}catch(IOException e){
System.out.println("文件不存在");
}
。。。。
fw.close(); //关闭流
使用BufferedWriter和FileWriter能提高字符流写文本文件的效率:
BufferedWriter是Writer的子类,带有缓冲区;
使用BufferedWriter写文件:
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.io.IOException; //引入相关类
FileWriter fw=new FileWriter("D:/test.txt");
BufferedWriter bw=new BufferedWriter(fw); //构造对象
bw.write("hello"); //写数据
bw.flush();
fw.close(); //关闭流
Writer常用方法:
write(String str);
write(String str, int off, int len);
void flush();
void close();
子类BufferedWriter()常用的构造方法:
BufferedWriter(Writer out); //注意参数是Writer 类型,确切的说是FileWriter类型;
读写二进制文件:
DataInputStream类:
1,是FileInputStream的子类;
2,与FileInputStream类结合可以读取二进制文件;
DataInputStream类:
1,是FileOutputStream的子类;
2,与FileOutputStream类结合可以写二进制文件;
使用DataInputStream类读取二进制文件:
import java.io.DataInputStream;
import java.io.FileInputStream; //引入相关类
FileInputStream fis=new FileInputStream("D:/test.txt"); //构造数据输入流对象
DataInputStream dis=new DataInputStream(fis);
dis.read(); //调用read 方法读取文件,
dis.close(); //关闭流
使用DataOutputStream类写二进制文件:
import java.io.DataOutputStream;
import java.io.FileOutputStream; //引入相关类
FileOutputStream fos=new FileOutputStream("D:/test.txt");
DataOutputStream dos=new DataOutputStream(fos); //创建数据输出流对象
dos.write(1); //写二进制数据
dos.close(); //关闭输出流对象