JAVA笔记(十三)

package cn.itcast.dao.impl;

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

import cn.itcast.dao.UserDao;

import cn.itcast.pojo.User;

/**

* 这是用户操作的具体实现类(IO版)

*

* @author 风清扬

* @version V1.1

*/

public class UserDaoImpl implements UserDao {

// 为了保证文件一加载就创建

private static File file = new File("user.txt");

static {

try {

file.createNewFile();

} catch (IOException e) {

System.out.println("创建文件失败");

// e.printStackTrace();

}

}

@Override

public boolean isLogin(String username, String password) {

boolean flag = false;

BufferedReader br = null;

try {

// br = new BufferedReader(new FileReader("user.txt"));

br = new BufferedReader(new FileReader(file));

String line = null;

while ((line = br.readLine()) != null) {

// 用户名=密码

String[] datas = line.split("=");

if (datas[0].equals(username) && datas[1].equals(password)) {

flag = true;

break;

}

}

} catch (FileNotFoundException e) {

System.out.println("用户登录找不到信息所在的文件");

// e.printStackTrace();

} catch (IOException e) {

System.out.println("用户登录失败");

// e.printStackTrace();

} finally {

if (br != null) {

try {

br.close();

} catch (IOException e) {

System.out.println("用户登录释放资源失败");

// e.printStackTrace();

}

}

}

return flag;

}

@Override

public void regist(User user) {

/*

* 为了让注册的数据能够有一定的规则,我就自己定义了一个规则: 用户名=密码

*/

BufferedWriter bw = null;

try {

// bw = new BufferedWriter(new FileWriter("user.txt"));

// bw = new BufferedWriter(new FileWriter(file));

// 为了保证数据是追加写入,必须加true

bw = new BufferedWriter(new FileWriter(file, true));

bw.write(user.getUsername() + "=" + user.getPassword());

bw.newLine();

bw.flush();

} catch (IOException e) {

System.out.println("用户注册失败");

// e.printStackTrace();

} finally {

if (bw != null) {

try {

bw.close();

} catch (IOException e) {

System.out.println("用户注册释放资源失败");

// e.printStackTrace();

}

}

}

}

}

  1. 其他的流(了解),每种颜色代表一种大的流。

操作基本数据类型

(操作基本数据的流)

DataInputStream

DataOutputStream

内存操作流

操作字节数组

ByteArrayInputStream

ByteArrayOutputStream

操作字符数组

CharArrayReader

CharArrayWrite

操作字符串

StringReader

StringWriter

内存操作流一般用于处理临时信息,因为临时信息不需要保存,使用后就可以删除。

2:以第一个举例即可

ByteArrayOutputStream baos = new ByteArrayOutputStream();

baos.write("helloworld".getBytes());

baos.close();

byte[] bys = baos.toByteArray();

ByteArrayInputStream bais = new ByteArrayInputStream(bys);

int by = 0;

while ((by = bais.read()) != -1) {

System.out.println((char) by);

}

baos.close();

bais.close();

最后的close()可以不写,通过看源码可以知道这里什么都没有做。

打印流概述

:只有写,没有读。

字节流打印流

字符打印流

打印流特点

只能操作目的地,不能操作数据源。

可以操作任意类型的数据。

如果启动了自动刷新,能够自动刷新。

可以操作文件的流

打印流复制文本文件

System类中的字段:in,out。(标准的输入输出流)

它们各代表了系统标准的输入和输出设备。

默认输入设备是键盘,输出设备是显示器。

System.in的类型是InputStream.

(字节流)System.out的类型是PrintStream(字符打印流)

是OutputStream的子类FilterOutputStream 的子类.

RandomAccessFile概述

RandomAccessFile类不属于流,是Object类的子类。但它融合了InputStream和OutputStream的功能。支持对随机访问文件的读取和写入。【该类的构造方法的第二个参数就是读写文件的模式,一共有四种,用得最多的是rw】utf对应汉字的是3个字节,想读取就可以读取那个位置,是通过设置指针位置来实现的。

SequenceInputStream概述

(合并流)SequenceInputStream类可以将多个输入流串流在一起,合并为一个输入流,因此,该流也被称为合并流。

SequenceInputStream的构造方法

SequenceInputStream(InputStream s1, InputStream s2)

SequenceInputStream(Enumeration<? extends InputStream> e)

把多个文件的内容写入到一个文本文件

合并流的一个构造可以合并两个文件,有一个构造可以合并多个文件,但是需要注意的是,该多个流的合并需要用到vector集合的方法,所以就得创建该集合。

  1. 打印流如果启动了自动刷新,对于某些方法就可以不用刷新和换行了。(比如println())。 该流的底层也高效。
  2. 在jdk1.5之前,没有scanner这个类,为了使键盘输入数据就通过字符缓冲流包装标准输入流实现【BufferedReader br=new BufferedReader(new InputStream(System.in)).】
  3. 注意一点:字符流如果不能显示在控制台或者文件中,看看是否刷新缓冲区了。
  4. 序列化流:

序列化流

ObjectOutputStream

(写)反序列化流

ObjectInputStream

(读)序列化操作问题

为什么要实现序列化?

如何实现序列化?

序列化数据后,再次修改类文件,读取数据会出问题,如何解决呢?

使用transient关键字声明不需要序列化的成员变量

对象序列化是将对象状态转换为可保持或传输的过程。一般的格式是与平台无关的二进制流,可以将这种二进制流持久保存在磁盘上,也可以通过网络将这种二进制流传输到另一个网络结点。

对象反序列化,是指把这种二进制流数据还原成对象。

Properties概述

Properties作为Map集合的使用

,(但是不能有泛型)Properties的特殊功能

public Object setProperty(String key,String value)

【添加元素】public String getProperty(String key)

【获取元素】public Set<String> stringPropertyNames()

【获取所有键的集合】Properties和IO流的结合使用

public void load(Reader reader)

【把文件的数据读取到集合中】public void store(Writer writer,String comments)

【把集合中的数据存储到文件】注意这里的集合只能是Priperties.这个文件的数据也必须是键值对形式。该集合可以应用于单机游戏状态的存贮。

NIO其实就是新IO的意思。

JDK4出现NIO。新IO和传统的IO有相同的目的,都是用于进行输入输出的,但新IO使用了不同的方式来处理输入输出,采用内存映射文件的方式,将文件或者文件的一段区域映射到内存中,就可以像访问内存一样的来访问文件了,这种方式效率比旧IO要高很多,但是目前好多地方我们看到的还是旧IO的引用,所以我们仍以旧IO为主,知道NIO即可。Buffer(缓冲),Channer(通道)

JDK7要了解的新IO类

Path:与平台无关的路径。

Paths:包含了返回Path的静态方法。

public static Path get(URI uri):根据给定的URI来确定文件路径。

Files:操作文件的工具类。提供了大量的方法,简单了解如下方法

public static long copy(Path source, OutputStream out) :复制文件

public static Path write(Path path, Iterable<? extends CharSequence> lines, Charset cs, OpenOption... options):

把集合的数据写到文件。

//复制文件

Files.copy(Paths.get("Demo.java"), newFileOutputStream("Copy.Java"));

//把集合中的数据写到文件

List<String> list = new ArrayList<String>();

list.add("hello");

list.add("world");

list.add("java");

Files.write(Paths.get("list.txt"), list, Charset.forName("gbk"));

  1. 要想实现序列化和反序列化就必须实现serializable接口,该接口中没有任何方法,在java中,没有任何方法的接口称为标记接口。
  2. 看到类实现了序列化接口的时候,要想解决黄色警告线的问题,就可以产生一个序列化id值,而且产生这个值以后,我们对类进行任何改动,它读取以前的数据是没有问题的。
  3. 打印流复制文件代码

BufferedReader br = new BufferedReader(new FileReader("a.txt"));

PrintWriter pw = new PrintWriter(new FileWriter("b.txt"),true);

String line = null;

while((line=br.readLine())!=null) {

pw.println(line);

}

pw.close();

br.close();

  1. Jdk1.7新特性的代码【了解使用】

package cn.itcast_09;

import java.io.IOException;

import java.nio.charset.Charset;

import java.nio.file.Files;

import java.nio.file.Paths;

import java.util.ArrayList;

/*

* nio包在JDK4出现,提供了IO流的操作效率。但是目前还不是大范围的使用。

* 有空的话了解下,有问题再问我。

* JDK7的之后的nio:

* Path:路径

* Paths:有一个静态方法返回一个路径

*               public static Path get(URI uri)

* Files:提供了静态方法供我们使用

*               public static long copy(Path source,OutputStream out):复制文件

*               public static Path write(Path path,Iterable<? extends CharSequence> lines,Charset cs,OpenOption... options)

*/

public class NIODemo {

public static void main(String[] args) throws IOException {

// public static long copy(Path source,OutputStream out)

// Files.copy(Paths.get("ByteArrayStreamDemo.java"), new

// FileOutputStream(

// "Copy.java"));

ArrayList<String> array = new ArrayList<String>();

array.add("hello");

array.add("world");

array.add("java");

Files.write(Paths.get("array.txt"), array, Charset.forName("GBK"));

}

}

  1. Properties的经典代码

package cn.itcast_08;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

import java.io.Reader;

import java.io.Writer;

import java.util.Properties;

/*

* 这里的集合必须是Properties集合:

* public void load(Reader reader):把文件中的数据读取到集合中

* public void store(Writer writer,String comments):把集合中的数据存储到文件

* 单机版游戏:

*               进度保存和加载。

*               三国群英传,三国志,仙剑奇侠传...

*

*               吕布=1

*               方天画戟=1

*/

public class PropertiesDemo3 {

public static void main(String[] args) throws IOException {

// myLoad();

myStore();

}

private static void myStore() throws IOException {

// 创建集合对象

Properties prop = new Properties();

prop.setProperty("林青霞", "27");

prop.setProperty("武鑫", "30");

prop.setProperty("刘晓曲", "18");

//public void store(Writer writer,String comments):把集合中的数据存储到文件

Writer w = new FileWriter("name.txt");

prop.store(w, "helloworld");

w.close();

}

private static void myLoad() throws IOException {

Properties prop = new Properties();

// public void load(Reader reader):把文件中的数据读取到集合中

// 注意:这个文件的数据必须是键值对形式

Reader r = new FileReader("prop.txt");

prop.load(r);

r.close();

System.out.println("prop:" + prop);

}

}

  1. 游戏设置次数的代码

package cn.itcast_08;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

import java.io.Reader;

import java.io.Writer;

import java.util.Properties;

/*

* 我有一个猜数字小游戏的程序,请写一个程序实现在测试类中只能用5次,超过5次提示:游戏试玩已结束,请付费。

*/

public class PropertiesTest2 {

public static void main(String[] args) throws IOException {

// 读取某个地方的数据,如果次数不大于5,可以继续玩。否则就提示"游戏试玩已结束,请付费。"

// 创建一个文件

// File file = new File("count.txt");

// if (!file.exists()) {

// file.createNewFile();

// }

// 把数据加载到集合中

Properties prop = new Properties();

Reader r = new FileReader("count.txt");

prop.load(r);

r.close();

// 我自己的程序,我当然知道里面的键是谁

String value = prop.getProperty("count");

int number = Integer.parseInt(value);

if (number > 5) {

System.out.println("游戏试玩已结束,请付费。");

System.exit(0);

} else {

number++;

prop.setProperty("count", String.valueOf(number));

Writer w = new FileWriter("count.txt");

prop.store(w, null);

w.close();

GuessNumber.start();

}

}

}

  1. 如果程序只有一条执行路径,那么该程序就是单线程程序,如果程序有多条【大于等于2】执行路径,那么该程序就是多线程程序。
  2. 进程就是正在运行的程序,多进程的意义就是提高cpu的使用率,在同一时间段同时运行,但是同一时间点是不可能的。
  3. 在同一个进程中又可以执行多个任务,而这每一个任务就可以看做是一个线程,多线程可以是进程拥有更大的几率抢到cpu资源,从而提高了程序的使用率。
  4. 我们不敢保证哪一个线程在某一时刻抢到资源,所以线程的执行是随机的。
  5. 并行(同一时间段)并发(同一时间点)
  6. Jvm的启动其实是多线程的,除了主线程之外,垃圾回收线程也会先启动,否则容易造成内存溢出,所以java虚拟机最低启动了两个线程。
  7. 实现多线程的2个方法【其实是3个】1.继承thread类,重写该类中的run()方法。2. 实现Runnable接口3.(了解)、使用ExecutorService、Callable、Future实现有返回结果的多线程
  8. 不是类中的所有代码都需要被(多)线程执行,这个时候,为了区分哪些代码能够被(多)线程执行,java就提供了thread类中的run()用来包含哪些被(多)线程执行的代码。 一般来说,被线程执行的代码都是比较耗时的,所以比较简单的就没有必要开创线程。
  9. Run()和start()方法的区别:run()仅仅是封装了线程执行的代码,直接调用跟普通方法一样。Start()方法首先启动了线程,然后再有jvm去调用该线程的run() 方法。
  10. 针对不是thread类的子类如何获取线程对象的名称?public static thread currenthread():返回当前线程的对象,然后在getname()即可。
  11. Java使用的是抢占模型:优先级高的获得cpu的时间片就多,同一优先级就随便获取一个。
  12. 线程的默认优先级是5.线程的优先级的范围是1~10,最小的是1,最大的是10.
  13. 线程的优先级高仅仅表示线程获取的cpu的时间片的几率高一些,但是要多次运行比较后才能得到比较好的效果,否则一两次有随机性,并不能很好的展现出结果。
  14. 线程的一些控制方法

线程休眠

public static void sleep(long millis)

【以毫秒为单位】

线程加入

【等待该线程终止,别的线程才可以抢】

public final void join()

线程礼让

【暂停当前正在执行的线程对象,并执行其他线程,它可以让多个线程的执行更和谐,但是不能保证一人一次】

public static void yield()

后台线程

【将该线程记为守护线程或用户线程,当正在运行的线程是守护线程时,java虚拟机退出,该方法必须在启动线程前调用】

public final void setDaemon(boolean on)

中断线程

public final void stop()

【让线程停止,已经过时了,不过还可以用,太过暴力,直接停止了,后面的代码就不能运行】

public void interrupt()

【中断线程,把线程的状态终止,并抛出一个异常,好让的代码运行】

  1. 线程的生命周期
  1. 实现runnable接口也同样要重写run()方法。然后创建实现类的对象,在创建thread类的对象,将实现类作为参数传递。
  2. 实现runnable接口的好处

实现接口方式的好处

可以避免由于Java单继承带来的局限性。

适合多个相同程序的代码去处理同一个资源的情况,把线程同程序的代码,数据有效分离,较好的体现了面向对象的设计思想。

  1. 为了实现共享一种资源,可以将这个资源定义为静态的。
  2. 加入延时后买票出现的问题

相同的票出现多次:

CPU的一次操作必须是原子性的

还出现了负数的票:

随机性和延迟导致的

package cn.itcast_08;

public class SellTicket implements Runnable {

// 定义100张票

private int tickets = 100;

@Override

//    public void run() {

//           while (true) {

//                  // t1,t2,t3三个线程

//                  // 这一次的tickets = 100;

//                  if (tickets > 0) {

//                         // 为了模拟更真实的场景,我们稍作休息

//                         try {

//                                Thread.sleep(100); // t1就稍作休息,t2就稍作休息

//                         } catch (InterruptedException e) {

//                                e.printStackTrace();

//                         }

//

//                         System.out.println(Thread.currentThread().getName() + "正在出售第"

//                                       + (tickets--) + "张票");

//                         // 理想状态:

//                         // 窗口1正在出售第100张票

//                         // 窗口2正在出售第99张票

//                         // 但是呢?

//                         // CPU的每一次执行必须是一个原子性(最简单基本的)的操作。

//                         // 先记录以前的值

//                         // 接着把ticket--

//                         // 然后输出以前的值(t2来了)

//                         // ticket的值就变成了99

//                         // 窗口1正在出售第100张票

//                         // 窗口2正在出售第100张票

//

//                  }

//           }

//    }

@Override

public void run() {

while (true) {

// t1,t2,t3三个线程

// 这一次的tickets = 1;

if (tickets > 0) {

// 为了模拟更真实的场景,我们稍作休息

try {

Thread.sleep(100); //t1进来了并休息,t2进来了并休息,t3进来了并休息,

} catch (InterruptedException e) {

e.printStackTrace();

}System.out.println(Thread.currentThread().getName() + "正在出售第"

+ (tickets--) + "张票");

//窗口1正在出售第1张票,tickets=0

//窗口2正在出售第0张票,tickets=-1

//窗口3正在出售第-1张票,tickets=-2

}

}

}

}

  1. 解决线程安全问题的基本思想

首先想为什么出现问题?(也是我们判断是否有问题的标准)

是否是多线程环境

是否有共享数据

是否有多条语句操作共享数据

如何解决多线程安全问题呢?

基本思想:让程序没有安全问题的环境。

怎么实现呢?

把多个语句操作共享数据的代码给锁起来,让任意时刻只能有一个线程执行即可。

  1. 同步代码块(可以解决线程安全问题)

同步代码块

格式:

synchronized(对象){需要同步的代码;}

同步可以解决安全问题的根本原因就在那个对象上。该对象如同锁的功能。(这个对象要形成唯一的一把”锁”,定义成成员变量为佳)

  1. 买票的完美代码:

package cn.itcast_10;

public class SellTicket implements Runnable {

// 定义100张票

private int tickets = 100;

// 定义同一把锁

private Object obj = new Object();

@Override

public void run() {

while (true) {

// t1,t2,t3都能走到这里

// 假设t1抢到CPU的执行权,t1就要进来

// 假设t2抢到CPU的执行权,t2就要进来,发现门是关着的,进不去。所以就等着。

// 门(开,关)

synchronized (obj) { // 发现这里的代码将来是会被锁上的,所以t1进来后,就锁了。(关)

if (tickets > 0) {

try {

Thread.sleep(100); // t1就睡眠了

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()

+ "正在出售第" + (tickets--) + "张票 ");

//窗口1正在出售第100张票

}

} //t1就出来可,然后就开门。(开)

}

}

}

package cn.itcast_10;

/*

* 举例:

*               火车上厕所。

* 同步的特点:

*               前提:

*                      多个线程

*         解决问题的时候要注意:

*                多个线程使用的是同一个锁对象

* 同步的好处

*         同步的出现解决了多线程的安全问题。

* 同步的弊端

*         当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率。

*/

public class SellTicketDemo {

public static void main(String[] args) {

// 创建资源对象

SellTicket st = new SellTicket();

// 创建三个线程对象

Thread t1 = new Thread(st, "窗口1");

Thread t2 = new Thread(st, "窗口2");

Thread t3 = new Thread(st, "窗口3");

// 启动线程

t1.start();

t2.start();

t3.start();

}

}

  1. 同步方法的格式以及锁对象。格式:将同步关键字写到方法上,它的锁对象是this(表示当前对象),同步代码块的锁对象是任意对象。同步静态方法的对象是当前类的class文件【类的字节码文件对象】,因为只有该class文件才会在静态方法之前。

如何把一个线程不安全的集合类变成一个线程安全的集合类

用Collections工具类的方法即可。

  1. Lock是一个接口。(子类实现然后调用lock()和unlock()方法,此功能就如同synchronized一样,这是jdk1.5的新特性,最好用try…finally语句,因为这样不管怎样都会释放锁)
  2. 同步可能产生死锁。

死锁是指两个或者两个以上的线程在执行的过程中,因争夺资源产生的一种互相等待现象

  1. 线程间通信问题:不同种类的线程间针对同一个资源的操作。
  2. 消费者和生产者问题要用到等待唤醒机制。【这些方法在object类中,这些方法的调用必须通过锁对象调用】------->>待续
时间: 2024-08-07 08:37:14

JAVA笔记(十三)的相关文章

Java笔记十三.常用API-Runtime、Runable、System类

常用API-Runtime.Runable.System类 一.Runtime类 1.概述:Runtime类封装了Java命令本身的运行进程,即每个Java应用程序都会拥有一个Runtime类对象,当应用程序运行时,允许其通过这个对象与运行环境进行交互,但需要注意的是应用程序本身不能为自己创建Runtime类对象.Runtime类的许多方法与System中的方法想重复,我们不能直接创建Runtime实例,但可以通过静态方法Runtime.getRuntime获得正在运行的Runtime对象的引用

java之jvm学习笔记十三(jvm基本结构)

java之jvm学习笔记十三(jvm基本结构) 这一节,主要来学习jvm的基本结构,也就是概述.说是概述,内容很多,而且概念量也很大,不过关于概念方面,你不用担心,我完全有信心,让概念在你的脑子里变成图形,所以只要你有耐心,仔细,认真,并发挥你的想象力,这一章之后你会充满自信.当然,不是说看完本章,就对jvm了解了,jvm要学习的知识实在是非常的多.在你看完本节之后,后续我们还会来学jvm的细节,但是如果你在学习完本节的前提下去学习,再学习其他jvm的细节会事半功倍. 为了让你每一个知识点都有迹

Go语言学习笔记十三: Map集合

Go语言学习笔记十三: Map集合 Map在每种语言中基本都有,Java中是属于集合类Map,其包括HashMap, TreeMap等.而Python语言直接就属于一种类型,写法上比Java还简单. Go语言中Map的写法比Java简单些,比Python繁琐. 定义Map var x map[string]string x : = make(map[string]string) 写法上有些奇怪,map为关键字,右侧中括号内部为key的类型,中括号外部为value的类型.一般情况下使用逗号或者冒号

15.1-全栈Java笔记:Java事件模型是什么?事件控制的过程有哪几步??

应用前边两节上一章节的内容,大家可以完成一个简单的界面,但是没有任何的功能,界面完全是静态的,如果要实现具体功能的话,必须要学习事件模型. 事件模型简介及常见事件模型 对于采用了图形用户界面的程序来说,事件控制是非常重要的. 一个源(事件源)产生一个事件并把它(事件对象)送到一个或多个监听器那里,监听器只是简单地等待,直到它收到一个事件,一旦事件被接收,监听器将处理这些事件. 一个事件源必须注册监听器以便监听器可以接收关于一个特定事件的通知. 每种类型的事件都有其自己的注册方法,一般形式为: v

13.1-全栈Java笔记:打飞机游戏实战项目|AWT技术|MyGameFrame

简介和项目目标 通过游戏项目学习整个Java基础知识体系,我们做了精心的设计,让每一章知识都能获得应用. 比如:多线程用来实现动画效果.容器实现对于多发炮弹的存取和处理.常用类等等的应用. 寓教于乐,让大家迅速入门,更希望通过喜闻乐见的小游戏,让大家爱上编程,爱上"程序员". 老鸟建议 很多朋友会疑惑:"游戏项目,又不能拿到企业面试中,为什么要讲?" 这是一种太过于功利的想法.就像,我们说:"今天吃个馒头,又不是长高,为什么要吃呢?" 游戏项目的

Java笔记---部署 JavaWeb 项目到云服务器

一.前言 前面我们已经尝过了在云服务器上部署代码的甜头了,现在主菜就要上场了,那就是将我们的 JavaWeb 项目部署到云服务器上.兴奋吧?淡定淡定~ 二.项目部署 我们对于 Java Web 项目在本地机器(无论是 Windows 还是 Linux)上的部署已经了然于心了,那么对于在云服务器上部署 Java Web 项目又是如何操作的呢? 其实很简单,还是离不开 Web 项目部署的那三点: ① 基础的 JDK 环境 ② 一个 Web 服务器.如 Tomcat.JBoss ③ 一款数据库.如:m

JAVA 笔记 七

JAVA笔记七 this:就代表本类的对象,this代表它所在函数所属对象的引用简单说:那个对象在调用this所在的函数,this就代表那个对象静态:static 用法:是一个修饰符,用于修饰成员(成员变量,成员函数)当成员被静态修饰后,就多了一个调用方式,除了可以被对象调用外,还可以直接被类名调用.类名.静态成员static特点1.随着类的加载而加载2.优先于的对象存在3.被所有对象所共享4.可以直接被类名所调用实例变量和类变量的区别:1.存放位置. 类变量随着类的加载而存在与方法区中. 实例

JAVA笔记六

JAVA笔记总结六 把大象放入冰箱的几步: 面向对象的三个特征:封装,继承,多态 JAVA开发实际上就是找对象使用,没有对象就创建一个对象 找对象,建立对象,维护对象的关系 类和对象的关系:类是对现实生活中实物的描述: 对象就是这类事物,实实在在存在的个体 匿名对象:匿名对象可以作为参数进行传递也可以作为对象方法进行一次调用

java 笔记 String 和Stringbuffer

String 是一个类,而不是java中的基本数据类型. String s = "abc";  "abc"是一个对象,存放在常量池中.一旦被初始化就不能被更改了. s = "cde";  这里并没有改变字符串,而是使对象引用指向字符串cde: String s1 = new String("abc"); String s2 = "abc"; 这两者有什么不同,第一个有两个对象,一个是"abc&qu

14.5-全栈Java笔记:java.awt这些布局怎么写?|流式|边界|网格

布局管理器 读者会发现,如果使用坐标定位法(空布局),在一个比较复杂的界面上定位每个控件的坐标是一个非常麻烦的工作,而且在界面大小发生改变时,控件的绝对位置也不会随之发生改变.那么如果我们想让用户界面上的组件可以按照不同的方式进行排列怎么办?例如:可以依序水平排列,或者按网格方式进行排列等,其实每种排列方案都是指组件的一种"布局",要管理这些布局,就需要本节学习的布局管理器. 管理布局的类由java.awt包来提供,布局管理器是一组实现java.awt.LayoutManager接口的