本帖最后由 小石姐姐 于 2018-4-25 15:35 编辑
Java笔记
File类的概述和常用功能
File:文件和目录路径的抽象表示形式,File类的实例是不可变的 构造方法: File(String pathname):将指定的路径名转换成一个File对象 File(String parent,String child):根据指定的父路径和文件路径创建File对象 File(File parent,String child):根据制定的父路径对象和文件路径创建File对象 File的常用功能:
创建功能:boolean creatNewFile()
//当指定文件不存在是创建成功返回true,否则false boolean mkdir() // //当指定文件夹不存在是创建成功返回true,否则false boolean mkdirs() //创建指定文件夹,当文件夹所在的目录不存在,那就把所在目录也创建了 boolean createNewFile ( ) //创建一个新文件,返回是否创建成功 删除功能:boolean delete()
//删除指定文件或文件夹,当指定文件或文件夹存在时删除成功返回true,否则false 注:删除一个文件夹,文件夹下不能有其他的文件或文件夹 获取功能:
String getPath() : :返回创建File对象时给的路径 File getAbsoluteFile() : 以对象的形式返回对象所指向的绝对路径 String getAbsolutePath() : 返回File对象所指向的绝对路径 String getName() : 获取文件和文件夹的名称 String getParent(): 获取父路径的字符串 File getParentFile() : 获取父路径的File对象 long lastModified() : 以毫秒值形式返回最后的修改时间 long length() : 返回文件的字节数 修改功能:
boolean renameTo(File dest) : 将当前对象指向的路径修改为指定对象所指向的路劲 注意:不能改成重名的,重名改不了 判断功能:
boolean exists():判断文件或文件夹是否存在,存在返回true,否则false boolean isAbsolute(): 判断File对象指定的路径是否是文件,是true,否则false boolean isDirectory(): 判断File对象指定的路径是否是文件夹,是true,否则false boolean isFile():判断File对象指定的路径是否是文件,,是true,否则false boolean isHidden(): 判断File对象指定的路径是否是隐藏文件,是true,否则false 绝对路径:固定不可改变的路径,以盘符开头 相对路径:相对某个参照物,不能以盘符开头 在eclipse中相对路径对应当前项目的根目录 获取功能:
String [ ] list():获取当前路径下所有文件和目录名称() File dir = new File("D:\\111");
//返回指定目录中的所有子文件或子目录的名称
String [] list = dir.list();
for (String name : list) {
System.out.println(name);
}
//返回指定目录中的所有子文件或子目录的File对象
File [] files = dir.listFiles();
for (File file : files) {
System.out.println(file);
}
//返回当前系统中的所有根路径
File [] roots = File.listRoots();
for (File root : roots) {
System.out.println(root);
}获取目录里面所有的.java文件
public static void main(String[] args) {
File f = new File("src");
menth(f);
}
public static void menth(File file) {
if(!file.isDirectory()){
return;
}
File[] files = file.listFiles();
for (File f : files) {
if(f.isFile()){
if(f.getName().endsWith(".java")){
System.out.println(f.getName());
}
}else {
menth(f);
}
}
}删除目录和子目录下的文件
public static void main(String[] args) {
File file = new File("a");
methed(file);
}
public static void methed(File file) {
//判断是不是目录
if(file.isDirectory()){
//把子文件和子目录全部传入数组
File[] files = file.listFiles();
//遍历数组
for (File f : files) {
//判断是不是子文件
if(f.isFile()){
//是子文件就删除
System.out.println(f.getName());
f.delete();
}
//然后在判断是不是子目录
else if(f.isDirectory()){
//是子目录就在此调用这个方法继续删除里面的子文件和子目录
methed(f);
}
}
System.out.println(file.getName());
file.delete();
}
}IO字节流与IO字符流
IO流分类:
流向:
输入流 读取数据 FileReader Reader
输出流 写出数据 FileWriter Writer
数据类型
字节流(处理任何类型文件,包括文本文件)
字节输入流 读取数据 InputStream
子接输出流 写出数据 OutputStream
字符流(处理文本文件)
字符输入流 读取数据 Reader
字符输出流 写出数据 Writer字符和字节的区别:
字节:byte,数字,能够组成任何文件 字符:文本,既然是文本,肯定涉及编码问题,字符底层也是字节
//一次读写一个字符
int ch;
while((ch = fr.read()) != -1){
fw.write(ch);
}
//一次读写一个数组
int len;
char [] chs = new char [1024] ;
while((len = fr.read(chs)) != -1){
fw.write(chs);
}字节流用bty [ ] 数组 字符流用char [ ] 数组 标准流
InputStream :字节输入流,用来读取键盘录入的数据 PrintStream:字节输出流,将数据输出到命令行 字节流
OutoutStreamWriter :以操作字符流方式按字节流写出 InputStreamReader :以操作字符流方式按字节流读入 打印流
PrintWriter :具有自动刷新,自动换行的特点 对象流
ObjectInputStream :从文件中读入一个对象到内存中 ObjectOutputStream:将内存中的对象写入到文件中 集合
Properties :用于与IO流结合读取配置文件,键值对形式,实现Map(key-value) 乱码
乱码的原因:多种编码表差错了 字符串编码的转换 标准输入输出流概括
System类的类字段 in:标准输入流。键盘输入 是InputStream类,属于字节输入流。Input Stream in = System.in; out:标准输出流,将数据输出到控制台 是PrintStream,OutputStream的子类,属于字节输出流 OutputStream out = System.out; String类的相关方法
构造方法(作用byte [ ] 转 String) String(byte [ ] bys) 成员方法(作用String转 byte [ ]) byte [ ] getBytes() 转换流
OutputStreamWriter类
是Writer的子类,属于字符输出流,是字符输出流通向字节流的桥梁 作用:以写出字符流的方式编写代码(char,char[ ] ,String)而底层以字节流写出到文件(byte,byte [ ] ) 实现这种转换:Writer --> OutputStreamWriter --> OutputStream 读取文件打印到控制台
public static void main(String[] args) throws IOException {
//创建字符输入流
BufferedReader br = new BufferedReader(new FileReader("text.txt"));
//创建字符输出流,里面在匿名创建把字节流转成字符流(括号里面是能打印到控制台)
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
//遍历
String line;
while((line = br.readLine())!=null){
bw.write(line);
bw.newLine();
}
//关流
br.close();
bw.close();
}OutputStreamReader类
从控制台接受键盘录入,写入到文本文件
public static void main(String[] args) throws IOException {
//创建标准键盘录入流
InputStream in = System.in;
//把键盘录入的传入字节输入流并转成字符输入流
Reader r = new InputStreamReader(in);
//创建文件字符输出流
FileWriter fw = new FileWriter("text.txt");
//一次读写一个数组
int line;
char [] chs = new char[1024];
while((line = r.read(chs))!=-1){
fw.write(chs,0,line);
fw.flush();
}
r.close();
fw.close();
}打印流
PrintStream:字节打印流 PrintWriter:字符打印流,我们学的 特点
可以自动换行(Println) 不能输出字节,但是可以输出任意类型 通过某些配置,可以实现自动刷新(println、printf或format) 也是包装流,不具备写出功能 可以把字节输出流转换成字符输出流 只有一个输出流,因为打印全是输出流的操作(只能输出不能输入) 成员方法
write(String s):写一个字符串 print(String s):输出字符串,没有换行 println(String s):输出字符串并换行 printf: 写入文本自动换行
public static void main(String[] args) throws IOException {
//创建打印流对象
PrintWriter pw = new PrintWriter("t.txt");
//这是不能换行的
pw.write("hello");
//这是能换行的
pw.println("hello");
//关流
pw.close();
}自动刷新(添加使用println)
public static void main(String[] args) throws IOException {
//创建自动刷新打印流对象
PrintWriter pw = new PrintWriter(new FileWriter("t.txt"),true);
//换行的
pw.println("hello");
}复制文本
//创建输入流对象
BufferedReader br = new BufferedReader(new FileReader("text.txt"));
//创建打印流对象
PrintWriter pw = new PrintWriter(new FileWriter("a.txt"),true);
//遍历
String line;////用于存储每行的数据
while((line = br.readLine())!=null){
pw.println(line);
}
//关流
br.close();
pw.close();
}对象操作流
注意:使用对象输出流写出对象,只能使用对象输入流读取对象 只能将支持java.io.Serializable接口的对象写入流中 ObjectInputStream:字节输入流(往外面读)
构造方法 ObjectInputStream(InputStream in):创建对象输入流 成员方法 readObject():从对象输入流读取对象,一次只读取一个对象,当都不到时抛出异常 ObjectOutputStream:字节输出流(往里面写)
构造方法 ObjectOutputStream(OutputStream out):创建对象输出流 writeObject(Object o):将对象写入对象输出流 Serializable:序列号,是一个标识接口,只起标识作用,没有方法 例题
(创建Student类,实现Serializable接口,必须实现这个接口,里面重写toString方法和全参)(利用对象操作流,往文件写数据(ObjectOutputStream),然后在读取到控制台(ObjectInputStream))
public class Student implements Serializable {
String name;
int age;
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
}
public static void main(String[] args) throws IOException, IOException, Exception {
method();
//创建输入流对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));
//读取集合对象
Object boj = ois.readObject();
//强转为ArrayList
ArrayList<Student> list =(ArrayList<Student>) boj;
//遍历集合
for (Student student : list) {
//打印
System.out.println(student);
}
//关流
ois.close();
}
private static void method() throws IOException, FileNotFoundException {
//创建输出流对象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));
//创建集合
ArrayList<Student> list = new ArrayList<>();
//集合中添加Student的对象
list.add(new Student("zhangsan", 18));
//把集合添加到文本(输出流对象)
oos.writeObject(list);
//关流
oos.close();
}public static void main(String[] args) throws IOException, IOException {
//method();
//创建对象输入流
ObjectInputStream os = new ObjectInputStream(new FileInputStream("text.txt"));
//利用捕获异常的方式来控制读没读到末尾
try {
//弄一个死循环,读到最后会触发异常
while(true){
Object object = os.readObject();
System.out.println(object);
}
//触发异常,结束程序
} catch (Exception e) {
System.out.println("已经读到末尾了");
}
}
private static void method() throws IOException, FileNotFoundException {
//创建对象输出流的对象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("text.txt"));
//创建学生对象
Student s = new Student("zhangsan",18);
Student s1 = new Student("wangwu",20);
//写出学生对象
oos.writeObject(s);
oos.writeObject(s1);
//关流
oos.close();
}
}解决对实现序列号接口出现的黄色警告问题
实现了序列号接口,在类名哪儿有提示,选择随机的序列号(第二个) Properties概述(集合)
类似Map,也是有键值对的方式,添加的方式是setProperty() 构造方法:Properties() 成员方法 可以使用Map接口的方法 String getProperty(String key):根据键获取值,找不到该键,则返回null; String getProperty(String key,String defaultValue):根据键获取值,如果值不存在,则使用指定的默认值 void setProperty(String key,String value):设置键值对 键 = 值; Properties和io流结合的功能
从配置文件加载到Properties
load(InputStream in):从字节输入流中读取Properties load(Reader reader):和上面一样,只是流不同 从Properties集合写到配置文件
list(printStream out):将Properties输出到指定的输出流,并且添加一个注释,如果不想增加注释,可以添加null;
public static void main(String[] args) throws IOException {
//创建集合
Properties p = new Properties();
//将键值对存入集合
p.setProperty("CZBK001","zhangsan");
p.setProperty("CZBK002","lisi");
p.setProperty("CZBK002","wangwu");
//创建流对象
FileWriter fw =new FileWriter("e.properties");
//掉用集合的store方法写入数据到文件中
p.store(fw, "hello");
//使用list方法测试 //自动刷新
p.list(new PrintWriter(new FileWriter("f.properties"),true));
//加载配置文件
Properties newp = new Properties();
newp.load(new FileInputStream("f.properties"));
System.out.println(newp);
}遍历:
//获取所有的key,通过key获取value
Set<Object> keys = prpo.keySet();
for (Object key : keys) {
Object value = prpo.get(key);
System.out.println(key+"="+value);
}
//获取所有的结婚证对象
Set<Map.Entry<Object, Object>> entry =prpo.entrySet();
for (Entry<Object, Object> entry2 : entry) {
System.out.println(entry2);
}编码表
作用
把计算机底层的二级制数据转换成我们能看懂的字符 ASCII码表
美国标准码,包含26个英文字母的大写和小写,数字,符号 GB2313 ---> GBK
国标码 ---> 国标扩展码 有中文而且还包含ASCII Unicode ---> UTF-8
万国码,支持多国语言字符 ---> 前面的一种实现方式,长度可变的码表,一个字符占用1个或2个或3个字节 UTF-8: 长度可变的码表
ANSI:本地编码表 GBK ISO-8859-1:西方语言编码
Java中字符的编码
解决乱码: 第一种:前后码表一致 第二种:转成数组的时候,指定码表 例题(根据别的编码表)
public static void main(String[] args) throws IOException {
//定义字符串
String s = "键盘敲烂,月薪过万";
//将字符转换为数字,查询utf-8编码表
byte [] bytes = s.getBytes("utf-8");
//有了byte[] ,就有了数字,写到文件中
FileOutputStream fos = new FileOutputStream("a.txt");
//写byte[]数组,因为内容很少,直接写一次
fos.write(bytes);
fos.close();
//读取文件
FileInputStream fis = new FileInputStream("a.txt");
//读取字节数组
int len;
byte [] b = new byte[1024];
//循环遍历
while((len = fis.read(b))!=-1){
//将读取到的byte[],也就是数字,查询utf-8编码表,转换为字符
String string = new String(b,0,len,"utf-8");
//打印到控制台
System.out.println(string);
}
fis.close();
}进程
Process:一个程序在内存里面的执行区域(进程) Thread:一个进程中的一个执行路径(线程) 进程:当前正在运行的程序 线程:进程中的一个执行控制单位,执行路径 一个进程可以有一个线程,也可以有多个线程 单线程:效率低,安全性高 多线程:效率高,安全性低 多线程案例:360,迅雷下载等 进程可以有多个(界面能看见) 线程是运行在进程里面的,也可以是多个,依赖于进程(界面看不见) 进程 --->线程 (单线程) 进程 --->线程 --->线程 --->线程 。。。。。(多线程) 并发
一块儿发生,多线程就有可能并发 同步
sync:是指一步一步的执行,一个执行完再去执行下一个 单线程就是同步 异步
async,同时执行多个步骤,随机性,不一定执行那一步 多线程就是异步 同一个线程内的代码是同步执行的,不同线程的代码是异步执行的 阻塞
上行代码正在执行,还没有执行完,程序就会卡在这里,下一行代码就不能执行,必须等上一步执行完,才可以 Thread(线程)
Thread:一个进程中的一个执行路径(线程) 这个Thread实现了Runnable接口 创建线程
第一种
(这是两个类,一个继承Thread,另一个类创建那个类的对象,然后启动) 定义一个类继承这个Thread(线程),(自己定义的类里面) 然后从写run()方法,要做什么事情就放在run方法里面 创建上一个类的对象,(测试类里面) start()是启动线程,就是执行run()方法里面的内容 getName()是获取线程的名字 setName()改线程的名字 注意
(改名字setName,必须在run方法里面先获取名字getName) 类继承Tread ---> 重写run()方法 ---> (new 前面的类)创建前面类的对象 ---> 启动start() 多new一个前面的类,就是多线程,你new几个,就是几个线程。 第二种
类实现Runnable接口 ---> 重写run方法 ---> run()方法里面getName()的话,需要(Thread.currentThread().getName())这样去调用getName方法 ---> 创建前面类对象 ---> 创建Thread对象 ---> 把前面的类对象名字传到Thread线程里面 ---> 启动 main()是单线程 currentThread():当前线程 第二种的好处是:自己创建的线程,可以往里面传入不同的任务,这样就可以执行不同的任务了,第一种就只能执行一个固定的任务 Thread.sleep(100); 睡眠 火车站案例
public static void main(String[] args) {
//创建任务对象
TicketThread tt = new TicketThread();
//创建线程对象,并且把任务对象传进去
Thread thread = new Thread(tt);
//改名字
thread.setName("窗口1");
Thread thread2 = new Thread(tt);
thread2.setName("窗口2");
Thread thread3 =new Thread(tt);
thread3.setName("窗口3");
//开启
thread.start();
thread2.start();
thread3.start();
}
}
class TicketThread implements Runnable{
//定义共享的票
int tickets = 100;
//定义锁对象,锁对象必须要被所有线程共享
Object obj = new Object();
@Override
public void run() {
//出售火车票
//循环
while(true){
//加一个同步代码块,相当于加了一把锁,把要执行的语句放在里面
synchronized (obj) {
//判断,票数小于0的时候就停止卖票
if(tickets > 0){
//捕获异常
try {
//让程序睡一会儿
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//打印卖了多少张票
System.out.println(Thread.currentThread().getName()+"="+tickets);
//买一张,就减一张
tickets--;
}
}
}
}同步代码块(锁对象)
锁对象必须是唯一的 synchronized:同步,可以修饰代码块和方法,被修饰的代码块一旦被某个线程访问则直接锁住,其他的线程将无法访问 格式:
锁对象可以是static修饰的,也可以是getclass(),后面的最好 synchronized(锁对象){ //要同步执行的代码 } 注意:锁对象需要被所有的线程所贡献 同步方法
就是一个使用synchronized修饰的方法,一旦被一个线程访问,则全部锁死,其他线程则无法访问,静态方法和非静态方法锁对象不一样 定义一个方法,在void前面加synchronized,就相当于把整个方法加上了锁 非静态的方法同步方法的锁对象是this 静态的方法同步方法是当前类的字节码对象 静态是static,非静态是不加
class tickets implements Runnable{
int s = 100;
Object obj = new Object();
@Override
public void run() {
while(true){
method();
}
}
private synchronized void method() {
if(s > 0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"="+s--);
}
}
}网络编程
Socket:(套接字)【记住】 是描述IP地址和端口,是一种网络编程机制,通信两端都有Socket 网络通信三要素
传输协议
作用:通信的规则 TCP
传输控制协议【必须建立连接,效率会降低,会形成传输数据的通道,是可靠协议】 Socket【发送端】 ServerSocket【接收端】 输出【发送数据】输入【接受数据】流,来当管道 字节的,getOutputStream【发送数据】 场合
适合准确性要求强的场合,比如金融系统,视频点播,【看视频】用户可以等待数据传输,但是不能忍受错误 UDP
用户数据报协议【不需要建立连接,数据报大小限制在64k,效率快,速度快,但是不可靠】【QQ电话,微信电话】 java.net.DatagramSocker类:基于UDP协议的Socket 构造方法
DatagramSocker():创建DatagramSocker对象,随机分配端口号 DatagramSocker(int port):创建DatagramSocker对象,指定端口号 成员方法
void send(DatagramPacket p):发送数据包 void receive(DatagramPacket p):接收数据,数据保存DatagramPacket对象中 void close():关闭通信,释放资源 场合
适合实时性要求强的场合,比如网络电话等环境,这种协议延迟很小,就好像打电话卡了,听不见了,听不见就听不见了,不会从新发送 如何写
DatagramPacket(byte [ ] msg,int msgLenght , InetAddress host , int port):创建数据包对象指定数据,目标主机对象,端口 DatagramPacket(byte [ ] buf , int length):创建数据包对象,接收数据为length的数据,存入byte数组中 inetAddress getAddress():获取数据包发送方的InetAddress对象 1:创建发送端Socket对象 2:创建数据并打包 3:发送数据send 打包【DatagramPacket】--数据(字节byte)+ 数据长度 + IP地址 + 端口 IP地址
InetAddress:IP地址 作用:网络设备的标识 IPv4:192.168.100.255【每位0~255,32位,4个无符号byte】点分十进制表示 IPv6:【128位,16个无符号byte】 IP可以使用主机名或者域名代替,更容易记忆 端口号
作用:标识使用网络通信的进程的逻辑地址,用于定位一个主机上的具体服务 【0~65535】【前1024个端口不要使用,是系统保留端口号】 常见服务占用的端口 查看端口号:netstat ~an http:// 192.168.1.1: 8080
-------- ------------ ------
通信协议 IP 端口号本地IP --- 本地端口号 ----------> 目标IP --- 目标端口号 InetAddress概述和测试
java.net.InetAddress类:用于标识IP地址对象(包含IP地址和主机名) getLocalHost():获取本机的InetAddress对象 getByName(String host):根据主机名或IP的字符串获取主机的InetAddress对象 getLoopbackAddress():获取回环地址的InetAddress对象,即127.0.0.1或者localhost getByAddress(byte [ ] addr):根据IP获取InetAddress对象 getHostAddress():返回主机的IP地址 getHostName():返回主机名 UDP协议发接数据
发送数据
public static void main(String[] args) throws IOException {
//创建发送方Socket对象
DatagramSocket sd = new DatagramSocket();
//打包,源数据,
String s ="hello, im coming";
//转换成字节
byte[] bytes = s.getBytes();
//源数据长度
int length = bytes.length;
//获取IP地址(这是自己的)
InetAddress localHost = InetAddress.getLocalHost();
//发送的端口号
int prue = 8888;
//把上面数据传进来,打包
DatagramPacket bao = new DatagramPacket(bytes, length, localHost, prue);
//把包发出去
sd.send(bao);
释放资源
sd.close();
}接受数据
public static void main(String[] args) throws IOException {
//定义接收端(端口要与发送端一致)
DatagramSocket ds = new DatagramSocket(8888);
//定义一个空数组,用于接受数据
byte [] byt = new byte[1024];
//把空数组传进数据报包
DatagramPacket dp = new DatagramPacket(byt, byt.length);
//接受数据,阻塞
ds.receive(dp);
//获取发送端的IP地址
InetAddress address = dp.getAddress();
//把内容转成字节数组
byte[] data = dp.getData();
//获取长度
int length = dp.getLength();
//打印IP地址,还要把字节数组转成字符串,字节数组,从0到最后获取的内容。
System.out.println(address+" "+new String(data,0,length));
//管
ds.close();
}TCP协议接收数据
发送数据
public static void main(String[] args) throws IOException, IOException {
//创建发送方
Socket sk = new Socket(InetAddress.getLocalHost(), 10086);
//资源
OutputStream stream = sk.getOutputStream();
String s = "Hello tcp,im coming!!";
stream.write(s.getBytes());
sk.close();
}接受数据
public static void main(String[] args) throws IOException {
//创建接受服务端对象
ServerSocket ss = new ServerSocket(10086);
//侦听并接受到此套接字的连接。此方法在连接传入之前一直阻塞。 【算是接受吧】
Socket accept = ss.accept();
//从服务端获取的,获取一个输入流,
InputStream in = accept.getInputStream();
//定义一个数组
byte [] by = new byte[1024];
//用于接受输入流解析的内容
int len;
len = in.read(by);
//把数组里面的内容转成字符串
String s = new String(by, 0, len);
//获取对方的IP地址
InetAddress localAddress = accept.getLocalAddress();
System.out.println(localAddress);
System.out.println(s);
}模拟用户登陆
客户端(发送)
package 上课05;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class Test01 {
public static void main(String[] args) throws IOException, IOException {
//创建客户端对象,明确地址,和端口
Socket sk = new Socket("DESKTOP-I4TOGSP",8888);
//写账号和密码
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入账号:");
String 账号 = br.readLine();
System.out.println("请输入密码:");
String 密码 = br.readLine();
//写出数据
//一次写出一行
PrintWriter pw = new PrintWriter(sk.getOutputStream(),true);
pw.println(账号);
pw.println(密码);
//接受数据
BufferedReader s = new BufferedReader(new InputStreamReader(sk.getInputStream()));
//读一行
String readLine = s.readLine();
System.out.println(readLine);
sk.close();
}
}服务端(接收)(发送)
package 上课05;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Test02 {
public static void main(String[] args) throws IOException {
//创建服务端对象,明确端口
ServerSocket ss = new ServerSocket(8888);
//阻塞,接收
Socket accept = ss.accept();
//读取内容
BufferedReader br = new BufferedReader(new InputStreamReader(accept.getInputStream()));
//一次读一行
String 账号 = br.readLine();
String 密码 = br.readLine();
//添加判断
boolean s =false;
//把账号和密码存入自己定义的那个类
User user = new User(账号,密码);
//判断和集合中的账号和密码是否一样
if(UserDB.Userlist().contains(user)){
//一样就true
s=true;
}
//返回数据
PrintWriter pw = new PrintWriter(accept.getOutputStream(),true);
//是true就登陆成功
if(s){
pw.println("登陆成功");
}else{
pw.println("登陆失败");
}
//释放资源
accept.close();
}
}模拟的数据库
package 上课05;
import java.util.ArrayList;
import java.util.List;
public class UserDB {
//定义静态方法
private static List<User> list = new ArrayList<>();
//利用静态代码块,添加元素
static{
list.add(new User("IP001", "121"));
list.add(new User("IP002", "122"));
list.add(new User("IP003", "123"));
list.add(new User("IP004", "124"));
}
//因为上面全是静态的,定义一个公共的类,返回上面的集合
public static List<User> Userlist(){
return list;
}
}数据库类
package 上课05;
public class User {
//定义账号
private String 账号;
//定义密码
private String 密码;
//无参
//全参
//get / set 方法
//重写equals方法【可以不要hashCode方法,删了就好】
【【上面的方法要都写出来】】反射
Reflect:在运行时,我们可以获取任意一个类的所有方法和属性 Reflect:在运行时,让我们调用任意一个对象的所有方法和属性 反射的前提
要获取类的对象(Class 对象)(字节码对象) java.lang.Class类:类的字节码对象 获取构造方法
fetConstructors():以数组形式返回该类中所有public的构造方法,如果没有public,则数组长度为0 getDeclaredConstruction:以数组形式返回该类中所有权限的改造方法,报货private,如果该类是接口,基本类型,数组,void,则数组长度为0 getConstruction(Class< ? >...parameterTypes()):根据参数列表返回指定的public的构造方法 获取对象类的字节码对象
Class clazz = Class.forName("上课01.Student");通过对象类的字节码对象,获取构造方法
//通过Student类的字节码对象,获取构造方法
Constructor[] cons = clazz.getConstructors();
for (Constructor constructor : cons) {
System.out.println(constructor);
}这是无参
Constructor con2 = clazz.getConstructor();
Object newInstance = con2.newInstance(); System.out.println(newInstance);这是有参
//获取有参构造方法,传入具体参数列表类型的字节码对象(还可以更改参数)
Constructor con = clazz.getConstructor(String.class,int.class);
Object newInstance2 = con.newInstance("张三",12); System.out.println(newInstance2);Class也能调用newInstance()方法
//Class类中也有newInstance()方法,只能调用无参构造
Object stu = clazz.newInstance();
System.out.println(stu);反射获取public成员变量:设置和获取值
Java.lang.Class类中的获取成员变量的方法 Field [ ] getFields():获取所有public的成员变量
Field[] fields = clazz.getFields();
for (Field f : fields) {
System.out.println(f);
}Field [ ] getDeclaredFields():获取所有权限的成员变量,包括private的
Field[] fields2 = clazz.getDeclaredFields();
for (Field f2 : fields2) {
System.out.println(f2);
}Field getField(String fieldName):通过指定的成员变量名获取指定的public的成员变量
Field f3 = clazz.getField("age");Field getDeclaredFields(String fieldName):通过指定的成员变量名获取指定的所有权限的成员变量,包括private的
Field declaredField = clazz.getDeclaredField("name");
System.out.println(declaredField);java.lang.reflect.Field类:成员变量对象 Object get(Objective obj):获取指定对象的属性值,传入对象,返回该对象的属性
Object object2 = f3.get(obj);通过反射获取私有成员变量并使用
setAccessible():暴力访问
//获取学生类的字节码对象
Class clazz = Class.forName("上课02.Student");
//获取学生对象
Object obj = clazz.newInstance();
//获取私有的字段对象
//Field[] getDeclaredField(String fieldName)
Field f = clazz.getDeclaredField("name");
//设置反射时取消Java的访问检查暴力访问
f.setAccessible(true);
System.out.println(f);
//设置值
f.set(obj, "lisi");
//修改值
Object name = f.get(obj);
System.out.println(name);反射获取成员方法并调用 getMethods():返回所有public的方法数组 getDeclaredMethods();返回所有权限的方法数组 Method getMethods():获取public的方法,传入方法名和方法形参字节码对象 Method getDeclaredMethods():获取所有权限的指定方法,传入方法名和方法形参字节码对象 java.lang.reflect.Method
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
//获取学生类的字节码对象
Class clazz = Class.forName("上课02.Student");
//获取学生类的对象
Object student = clazz.newInstance();
//获取无参无返回值的方法
Method m = clazz.getMethod("method");
m.invoke(student);
//获取有参无返回值的方法
Method m2 = clazz.getMethod("setName", String.class);
m2.invoke(student, "lisi");
//获取无参有返回值的方法
Method m3 = clazz.getMethod("getName");
Object obj = m3.invoke(student);
System.out.println(obj);
}百度的
Class c=Class.forName("className");注明:className必须为全名,也就是得包含包名,比如,cn.netjava.pojo.UserInfo;
Object obj=c.newInstance();//创建对象的实例
OK,有了对象就什么都好办了,想要什么信息就有什么信息了。
获得构造函数的方法
Constructor getConstructor(Class[] params)//根据指定参数获得public构造器
Constructor[] getConstructors()//获得public的所有构造器
Constructor getDeclaredConstructor(Class[] params)//根据指定参数获得public和非public的构造器
Constructor[] getDeclaredConstructors()//获得public的所有构造器
获得类方法的方法
Method getMethod(String name, Class[] params),根据方法名,参数类型获得方法
Method[] getMethods()//获得所有的public方法
Method getDeclaredMethod(String name, Class[] params)//根据方法名和参数类型,获得public和非public的方法
Method[] getDeclaredMethods()//获得所以的public和非public方法
获得类中属性的方法
Field getField(String name)//根据变量名得到相应的public变量
Field[] getFields()//获得类中所以public的方法
Field getDeclaredField(String name)//根据方法名获得public和非public变量
Field[] getDeclaredFields()//获得类中所有的public和非public方法 JavaBean概述和规范 就是一个类 作用:封装数据 规范:类必须时public修饰的 通过private的成员变量保存数据 通过public的get/set方法操作数据 至少提供一个无参构造方法 实现Serializable接口(用于使用IO流传输对象到文件或网络) BeanUtils概述和jar包
需要往里面导入jar(炸包) 前提 :创建一个类(比如Person类)需要无参构造、有参构造、setter和getter方法, toString方法,实现序列化接口(Serializable),给一个序列号,导出异常的第二个,固定序列号, BeanUtils.setProperty ( 类对象,“类的成员”,“更改后的值” ) BeanUtils.getProperty(类对象,“需要获取类的成员的”); BeanUtils.populate(类对象, 需要传入的集合名字); static void setProperty(Object bean, String name, Object value) :设置值static String getProperty(Object bean, String name):获取值static void populate(Object bean, Map properties):批量设置对象属性
public static void main(String[] args) throws ReflectiveOperationException, InvocationTargetException {
Person p = new Person();
BeanUtils.setProperty(p, "name", "zhangsan");
BeanUtils.setProperty(p, "age", 18);
String name = BeanUtils.getProperty(p, "name");
System.out.println(name);
Map<String, Object> map = new HashMap<>();
map.put("name", "lisi");
map.put("age", 18);
map.put("gender", "男");
BeanUtils.populate(p, map);
System.out.println(p);
}自己定义工具类
里面包括设置属性值,获取属性值,批量赋值 package 上课04; import java.lang.reflect.Field; public class MyBeanUtils { //设置一个私有的方法 private MyBeanUtils(){} //这是设置属性值的方法 public static void setP(Object bean,String name,Object value) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { //通过传入的对象获取其字节码对象 Class clazz = bean.getClass(); //通过字节码对象获取指定名称的成员变量对象 Field f = clazz.getDeclaredField(name); //开启暴力访问 f.setAccessible(true); //设置属性值 f.set(bean, value); } //这是获取属性值的方法 public static String getProperty(Object bean,String name) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException { //通过传入的对象获取其字节码对象 Class clazz = bean.getClass(); //通过字节码对象获取指定名称的成员变量对象 Field f = clazz.getDeclaredField(name); //开启暴力访问 f.setAccessible(true); //获取属性值,传入的是对象的形参 Object value = f.get(bean); //转为字符串并返回 return value.toString(); } public static void populate(Object bean,Map map) throws ReflectiveOperationException, SecurityException { // Class clazz = bean.getClass(); //获取Map中所有的key Set keys = map.keySet(); for (Object key : keys) { //如果输入了不存在的变量成员,捕获 try{ //根据key来获取对应的Field的对象 Field f = clazz.getDeclaredField(key.toString()); //根据key来获取Map中对应的value Object value = map.get(key); //暴力获取 f.setAccessible(true); f.set(bean, value); }catch(NoSuchFieldException e){ e.printStackTrace(); } } } } package 上课04;
import java.util.HashMap;
import java.util.Map;
public class Test02 {
public static void main(String[] args) throws SecurityException, IllegalArgumentException, ReflectiveOperationException {
//创建Person对象
Person p = new Person();
//测试工具类
MyBeanUtils.setP(p, "name", "张三");
System.out.println(p);
String name = MyBeanUtils.getProperty(p, "name");
System.out.println(name);
//批量设置
Map map = new HashMap<>();
map.put("name", "zhangsan");
map.put("age", 18);
map.put("gender", "男");
//调用方法
MyBeanUtils.populate(p, map);
System.out.println(p);
}
}font 中间文字,前面的里面写颜色,字体大小,字体型号(color,size,face) < h1 >一直到< h6 >:标题标签 < hr >:横线 < p >:段落标签 < b >:字体加粗 < i >:斜体 < u >:加下划线 < center >:居中 & nbsp; 可以加在文字中,是空格 < pre > :文字原封不动的显示【原生标签】 图片
< img >:图片 src :图片的来源【路径】 width :图片的宽度【图片后面设置】 height :图片的高度【图片后面设置】 alt > :图片找不到显示的内容 ./是同级路径 ../上一级路径 ../../更上一级路径 img/上一级路径 有序列表
有序标签【type 类型 start:默认[1,2,3..] 数字类型[1],英文类型[a]罗马类型】【可以写大写】 < ol > < li >< /li > < /ol > start属性:从哪儿开始 无序列表
无序列表【type:前面显示的实心点[disc] 空心圆[circle]方块[square]】 < ul > < li >< /li > < /ul > 超链接
target < a >:超链接【属性:href 链接的路径,parent自身一小块区域打开】 href:超链接跳转的地址 target:打开的方式 _self :在自身页面打开 _blank :新打开一个窗口 表格标签
< table > < tr >这是几行 < td >< /td > :这是几列 < /tr > < /table > cellspacing:表格空隙 属性: width :表格宽度 Height:表格高度 Border:边框 Align:表格水平位置: left:左 center:居中 right:右 colspan:合并列 rowspan:合并行 表单标签
表单标签 :< form > 常用属性: action属性:提交的路径,默认提交到当前页面 method属性:请求的方式。GET和POST。默认GET 【面试题】GET方式和POST方式区别?【不仅仅只有这两个,有很多种】 GET:数据会显示到地址栏中【不安全】有大小限制 POST:数据不会显示到地址栏中【】 表单元素:< input type = "text" > :文本框 常用属性: name :表单元素的名称,必须有 value:文本框的默认值 size:文本框的长度 maxlength:文本框输入的最大长度 readonly:只读文本框 < input type = "password" > :密码框 常用属性: name :密码框的名称,必须有 value:密码框的默认值 size:密码框的长度 maxlength:密码框输入的最大长度 readonly:只读文本框 < input type = "radio" > :单选按钮 name :密码框的名称,必须有 、 readonly:只读文本框 checked:单选按钮默认选择 < input type = "checkbox" > :多选按钮 checked:多选按钮默认选择 < input type = "button" > :普通按钮,没有任何功能的按钮 < input type = "submit" > :提交按钮 < input type = "reset" > :重置按钮 < input type = "file" > :文件上传的表单项 < input type = "hidden" > :隐藏字段 < input type = "image" > :图片按钮 < select > :下拉列表 < option >:下拉列表里的内容 selected:谁是默认的 < textarea >:文本域 cols:列 rows:行 单选,多选,下拉列表,value值必须写的
|