开发环境:1-JDK 库、编译器、运行器等, 唯一的。 www.oracle.com 安装文件名:jdk-21_windows-x64_bin.exe
2-IDE 有很多种。eclipse www.eclipse.org 安装文件名:eclipse-inst-jre-win64.exe
对比C语言:
devC++:包含两个东西:1-库;2-IDE:集成开发环境
第一个Java程序:
1-创建Java project:项目名必须全小写
2-创建类,类(class)名首字母大写
Java程序是由若干个class组成的:
class Hello{
}
class World{
}
类是由函数组成
类和函数是没有排列次序
程序的执行入口:main()函数的第一行
程序的执行出口:main()函数的最后一行
java命名的约定:
项目名必须全小写
类(class)名首字母大写 StudentOfGupt
函数、变量名小写开头 studentOfGupt
常量名全大写 COUNT_OF_CLASS234
源码.java(src目录下), 字节码.class(bin目录下),文件名和类名是一模一样
source
bin--binary二进制
javaSE javaEE
第二章
定义变量:本质是在内存开辟空间,空间大小是由类型决定
+:当”+”两端都是数的时候,就做加法
当”+”左右有一端是字符串,首先把非字符串的一端转换为字符串,然后做字符串串接
当”+”左右两端都是字符串,做字符串串接
引深用法:把任何一个对象转成对应的字符串的方法: +""
Person类:定义了所有的人的共性,属性/行为
"类是不存在的,只有实例对象才存在"
两种创建某个类型的实例对象的情况:
1-
int a;
//内置类型
2-
Person lily = new Person();
//非内置类型
Scanner类的使用:
try-catch处理异常:
Scanner reader = new Scanner(System.in);
String name;
int age;
System.out.print("input your name:");
name = reader.nextLine();
do {
try {
System.out.print("input your age:");
age = reader.nextInt(); //如果这句话抛出异常对象,就转去catch子句执行
break;
}catch(Exception e) { //catch子句只有当try中有语句抛出异常的时候才执行,否则就不执行
System.out.print("error age.");
reader.next(); //把上次在读入缓存中余下的回车字符串消耗掉
}
}while(true);
第三章:
if else
switch-case
for
do while
while
第四章 数组
批量数据结构,每个单元的类型必须相同或者相容
数组名本质是数组首地址
数组空间一定是连续空间,插入和删除需要循环移位
数组是不能整体操作,一次只能操作一个单元,要操作整个数组---用到循环
数组定义:
int[ ] arr = new int[10]; //要以最大的可能去开辟空间
int[] brr = {10,20,30,40};
凡是用new开辟的空间,是由默认初值的
任何数组都有length属性,得到数组的长度
Arrays类:fill() sort()
类名.方法名( )
Arrays.sort()
二维数组:
每一行长度一样:
int[][] arr = new int[3][4];
每一行长度不同:
int[][] brr = new int[3][];
brr[0] = new int[3];
brr[1] = new int[5];
brr[2] = new int[4];
Java包装类:Integer,Double,Float,Character,Boolean
包含对应数据类型可以直接调用的方法和一些常量,比如:Integer.MAX_VALUE,Integer.MIN_VALUE
String
java.lang.String
字符串常量:写在双引号中,所有的字符串常量在内存只保存一个副本
String s; //和int a;等同看待,类,对象(实例)
String类型的对象保存的都是字符串的首地址(所有的对象名都指代的是对象的首地址)
String对象在定义的时候可以不用new,可以常量字符串赋值
==:比的是字符串的首地址
s3.equals(s4)//比字符串的内容
特例:
String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2);//首地址相等,true
System.out.println(s1.equals(s2));//内容相等,true
不能在字符串上做修改,只能产生一个新的字符串:如果有大量的字符串改变操作,不适合用String。StringBuilder/StringBuffer
第五章
"类是不存在的,实例对象才是存在"
一、同一个类中的方法可以直接互相调用
class Bird{
void eat() {
System.out.println("eating...");
}void fly(){
System.out.println("fly...");
}
}
二、在一个类中调用第一个类中的方法go:
最一般情况:
1-创建类B的对象:B b = new B();
2-对象名.方法名():b.go();例如:
public class Test3 {
public static void main(String[] args) {
Bird b = new Bird();//1-创建类Bird的对象
b.eat();//2-对象名.方法名()
b.fly();
Test3 t = new Test3();//调用同一个类中的方法也是适用的
t.go;
}
void go() {
System.out.println("going...");
}
}
class Bird{
void eat() {
System.out.println("eating...");
}void fly(){
System.out.println("fly...");
}
}
三、类名.方法名()
public class Test4 {
public static void main(String[] args) {
System.out.println(Integer.MAX_VALUE);
int result = Integer.parseInt("1234");
System.out.println(result);
T.go();//static方法直接用类名调用
T t = new T(); //static方法也可以通过创建对象去调用
t.go();
}
}
class T{
static void go() {
System.out.println("go...");
}
}
四、static方法不能直接调用非static方法,也不能直接引用非static成员变量
static既可以修饰成员变量也可以修饰成员方法
五、类是由成员方法和成员变量组成
成员变量是所有成员方法共享的
public class Test1 {
int a; //成员变量
public static void main(String[] args) {
Test1 t = new Test1();
t.a = 3; //在static方法中访问非static成员变量
// a = 3;
}
public static void go() {
a = 2; //成员变量a
}
public void come() {
a = 3; //成员变量a
}
}
方法的定义和调用
方法的参数,返回
局部变量:在一个方法中定义的变量,只在当前方法里有效
使用一个类的两种方法:
public class Test5 {
public static void main(String[] args) {
JFrame f = new JFrame(); //使用一个类的方法一
MyPanel p = new MyPanel();
f.add(p);
f.setSize(500, 300);
f.setLocation(300, 400);
f.setVisible(true);
}
}
class MyPanel extends JPanel{ //使用一个类的方法二:继承
public void paint(Graphics g) {
g.setColor(new Color(255,0,0));
g.drawLine(30, 50, 300, 400);
g.setColor(new Color(0,255,0));
g.drawOval(100, 200, 30, 60);
g.fillOval(200, 300, 50, 50);
}
}
this
Java是单继承
extends 父类:继承父类所有的功能
implements 接口:实现接口,给出接口中所有的抽象方法以实现体
接口:就是一种特殊的类,是没有实现体的抽象方法组成
public class Test {
public static void main(String[] args) {
Son s = new Son();
s.go();
}
}
class A{
public void go() {
System.out.println("go in A.");
}
}
interface B{
public abstract void t1();
public abstract void t2();
}
class Son extends A{
}
class Son2 implements B{
public void t1() {
}
public void t2() {
}
}
异常:
程序员无法控制的情况,使得程序无法正常运行。比如,联网程序运行的时候的网络不通。---称为异常
还需要给与异常处理。
try{
1 //可能抛出异常的语句
2
3
}
catch(){}
catch(){}
catch(Exception e){}
finally{}
try中语句,如果没有抛出异常,那么所有的catch子句都不执行;
如果try中第2句抛出异常,try中后面的语句就不再执行,这个抛出的异常对象会依次和catch后面的异常类型匹配,
执行类型匹配的异常处理子句
catch子句,把父类异常(Exception )排在最后
finally子句,不管有没有异常都会执行的语句
RuntimeException:不处理是可以通过编译,其他所有的异常必须处理不然编译出错
第二种处理异常的方法:
在抛出异常的语句所在的方法头部生命抛出,不处理异常。有这个方法的调用者来处理异常。
1-异常不能推卸给用户
2-一般的异常都就近给与处理
主动抛出异常对象:
throw 异常对象
JavaSE类库的使用:
第8章 Java图形的界面实现
awt包,swing包
由组件(能够在界面上呈现的类)对象组合成界面
布局:
1-绝对布局:设定放入组件对象的坐标和大小--取消容器的布局管理器,
例如:
f.setLayout(null);//取消容器的布局管理器
b.setLocation(50, 50);
b.setSize(50, 20);
2-相对布局:给容器加入对象之前要设定容器的布局管理器。
BorderLayout:东西南北中
FlowLayout:
GridLayout:
JFrame:默认布局管理器是BorderLayout
JPanel:默认布局管理器是FlowLayout
3-嵌套布局
用JPanel
事件监听器:
1-写一个监听器的类:
1)实现某种监听器的接口
2)实现该接口规定的抽象方法
2-将监听器对象注册在负责监听的组件对象上
KeyLisenter
ActionListener
public class Test5 {
public static void main(String[] args) {
new Computer().make();
}
}
class Computer implements ActionListener{
String str1 = "";//运算数
String str = "";
String op;//运算符号
double result;
JTextField tResult;
public void make() {
JFrame f = new JFrame();
f.setLayout(new BorderLayout());
tResult = new JTextField();
f.add(tResult, BorderLayout.NORTH);
JPanel p = new JPanel();
p.setLayout(new GridLayout(4,4));
//在p放入16个按钮
JButton[] bts = new JButton[16];
String[] lbls = {"7","8","9","/","4","5","6","*","1","2","3","-","0",".","=","+"};
for(int i = 0;i < bts.length;i++) {
bts[i] = new JButton(lbls[i]);
p.add(bts[i]);
bts[i].addActionListener(this);
}
f.add(p,BorderLayout.CENTER);
f.setSize(200, 200);
f.setVisible(true);
}
public void actionPerformed(ActionEvent e) { //当按钮单击事件发生,要做的相应
String s = e.getActionCommand();
System.out.println(s);
if(s.equals("+") || s.equals("-") || s.equals("*") || s.equals("/")) {
str1 = str;
str = "";
op = s;
}else if(s.equals("=")){
//str1:第一个运算数,str:第二个运算数,op:运算符
switch(op) {
case "+":result = Double.parseDouble(str1) + Double.parseDouble(str);break;
case "-":result = Double.parseDouble(str1) - Double.parseDouble(str);break;
case "*":result = Double.parseDouble(str1) * Double.parseDouble(str);break;
case "/":result = Double.parseDouble(str1) / Double.parseDouble(str);break;
}
tResult.setText(result + "");
}else {
str = str + s;
}
}
}
//"101.5"+"2.66"=
//1-当+-*/:第一个运算数已经输入完成,将要开始第二个运算数的输入
//2-当=:第二个运算数已经输入完成,可以开始计算
//3-当前输入的字符串和之前输入的字符串串接起来
第10章 输入/输出(I/O) IO包
文件:外存数据
CPU只能处理内存中的数据(容量有限,不能永久保存),外存(容量大,永久保存)
数据在内存和外存之间的传递
输入(读入):从外存传递到内存
输出(写出):从内存传递到外存
"流"类:
抽象类:包含抽象方法的类。用来划分阵营,构成了架构;规定所有子类的共性
抽象类是不能实例化的
抽象方法:没有实现体。
public class Test2 {
public static void main(String[] args) {
Plane p = new Plane();
p.fly();
}
}
abstract class FlyTool{ //抽象类:包含抽象方法的类
public abstract void fly() ; //抽象方法:没有实现体
}
class Plane extends FlyTool{
public void fly() {
}
}
IO包"流"类分为4个阵营(方向和处理单位):
InputStream:输入字节流
OutputStream:输出字节流
Reader:输入字符流(适合于文本文件)
Writer:输出字符流
字节流:
//把一个图片文件读入内存---输入字节流FileInputStream/FileOutputStream:和外设创建连接,"节点流"
public class Test3 {
public static void main(String[] args) {
try {
FileInputStream fi = new FileInputStream("f:\\baidu.png");
byte[] arr = new byte[fi.available()]; //适合文件很小
fi.read(arr); //适合小文件
FileOutputStream fo = new FileOutputStream("f:\\baidu2.png");
fo.write(arr);
fi.close();
fo.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class Test4 {
public static void main(String[] args) {
try {
FileInputStream fi = new FileInputStream("f:\\baidu.png");
FileOutputStream fo = new FileOutputStream("f:\\baidu3.png");
byte[] arr = new byte[1000];
int n;
while(true) {
n = fi.read(arr);
if(n == -1) {
break;
}
fo.write(arr, 0, n);
}
fi.close();
fo.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
DataInputStream/DateOutputStream:"处理流"
把Java4种基本类型的数据转成二进制
不要大而全的模块。灵活的装配。"装饰器模式"
public class Test1 {
public static void main(String[] args) {
try {
FileOutputStream fo = new FileOutputStream("f:\\score.dat");
DataOutputStream dout = new DataOutputStream(fo);
dout.writeInt(98);
dout.writeDouble(88.5);
dout.writeBoolean(true);
dout.writeUTF("hello");
dout.close();
fo.close();
FileInputStream fi = new FileInputStream("f:\\score.dat");
DataInputStream din = new DataInputStream(fi);
System.out.println(din.readInt());
System.out.println(din.readDouble());
System.out.println(din.readBoolean());
System.out.println(din.readUTF());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
字符流:
FileReader/FileWriter:负责直接和外设创建连接BuffererReader/BufferedWrite/PrintWriter:以"句"为单位
public class Test3 {
public static void main(String[] args) {
try {
FileReader fr = new FileReader("f:\\letter.txt");
BufferedReader br = new BufferedReader(fr);
String str;
while((str = br.readLine()) != null) {
System.out.println(str);
}
fr.close();
FileWriter fw = new FileWriter("f:\\letter.txt",true);
BufferedWriter bw = new BufferedWriter(fw);
bw.write("first line.");
bw.newLine();
bw.write("second line.");
bw.newLine();
bw.write("third line.");
bw.flush(); //压缓存
bw.close();
fw.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
PrintWriter:不用手动换行和压缓存
FileWriter fw = new FileWriter("f:\\letter.txt",true); //true:追加
PrintWriter pw = new PrintWriter(fw,true); //true:自动压缓存
pw.println("hello1");
pw.println("hello2");
InputStreamReadered/OutputStreamWriter:字节流和字符流的转换流
典型的应用场景:通过网络发送字符串 聊天
File类
Java网络编程:
TCP/UDP
多线程:
服务器:同一个程序中有多道并行的执行
客户端:同时有"发送" "接收"
多线程:
一、概念
进程:同时处于运行状态的每一道程序(宏观并行,微观串行) CPU是轮传
线程:一个进程中有多道并行的线程
任何一个程序运行,自动启动main线程
二、两种实现多线程的方法:
实现多线程的方法一:每道线程相互独立
public class Test2 extends Thread{ //线程类
public void run() {
//当前线程的执行内容
}
}
public class Test1 {
public static void main(String[] args) {
Test2 t = new Test2();
t.start(); //具有争夺CPU的能力了.就绪状态
//t线程和main线程并行
}
}
实现多线程的方法二:线程之间是有关系的(争夺关系),多继承
任务类:
public class SaleTicket implements Runnable{ //任务类
int number = 0;
public void run() { // 当前任务要执行的内容
while(true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(number <= 10) {
System.out.println(Thread.currentThread().getName() + "-no." + number + "卖掉了.");
number++;
}else {
break;
}
}
}
}
多个线程同时执行一个任务:
public class Test3 {
public static void main(String[] args) {
SaleTicket t = new SaleTicket();
Thread t1 = new Thread(t,"窗口1");
Thread t2 = new Thread(t,"窗口2");
Thread t3 = new Thread(t,"窗口3");
t1.start();
t2.start();
t3.start();
}
}
三、线程的同步:对共享数据做修改的时候,线程要硬性的实现串行
加锁:尽量减少被加锁的代码
锁:任意对象,只能有一个
public class SaleTicket implements Runnable{ //任务类
int number = 0;
public void run() { // 当前任务要执行的内容
while(true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(this) { //用当前任务对象做"锁"
if(number <= 10) {
System.out.println(Thread.currentThread().getName() + "-no." + number + "卖掉了.");
number++;
}else {
break;
}
}
}
}
}
四:线程的通信
线程之间的相互关系:互相独立无关、争夺、通信、合作
第13章 容器类
批量数据管理
util包
数组:每个单元类型相同或相容,连续空间,按照最大可能开辟空间。不适合经常做插入删除,适合随机访问
链表:把不连续的空间串联起来,适合经常做插入删除,不适合随机访问
(接口:特殊的类,所有的成员方法都是抽象方法)
Collection接口:用来管理单个对象
List接口:有序,有下标,允许重复,允许有null
ArrayList类:底层以数组实现。不适合经常做插入删除,适合随机访问
LinkedList类:底层以链表实现。适合经常做插入删除,不适合随机访问
Set接口:无序,不允许重复
HashSet类:用来去重
TreeSet类:用排序
Map接口:用来管理"键值对"
key-value 对key做操作
HashMap类:
泛型
Iterator类
第15章
类的定义:成员变量和成员方法
1-封装:一般情况下,所有的成员变量private,所有的成员方法public
任何一个对象,不能直接操作他的某个成员变量,要以一个整体的方式去操作,可以做什么操作有这个类暴露了什么接口来控制
getter/setter方法
static成员变量:
static成员方法:和对象无关。类名.static方法()
继承:
去重
245页:26:
System.out.println(this.getName() + "is digging...")
35:
接口:
抽象类:
面向接口编程:并行开发
灵活替换---可维护性
275页
1行 20行
abstract class Question{
......
public abstract boolean check(String[] ans);
}
去掉22-24行
Question[] arr = new Question[2];
arr[0] = new SingleQuestion();
arr[1] = new MultiQuestion();
for(int i = 0;i < arr.length;i++){
arr[i].check();
}
把单选题和多选题在一个循环中统一循环