JAVA核心技术卷I——笔记

一、前言

从头JAVA,选择了先从JAVA核心技术这本书,先看的电子版(第七版)的,书是第九版的,卷一已经有很多不一样了,周六日看(先立个FLAG)。内容基本上都是知识点串记和注意点。

二、笔记

  1. 关于代码中的static变量或者代码块,是要在构造器之前初始化的。
  2. 编译器通过方法名和参数(方法的签名),如果方法不为private、static、final方法(静态绑定),则默认采用动态绑定(多态性)。
  3. final类和方法不允许被继承,final类默认为其类下的方法添加final
  4. 超类的关于比较的说明:
    == 比较基本域 equels 比较对象域 instanceOf 是否属于同一个类型的类
  5. equals 方法和hashCode方法
  6. Object基类中的toString方法,用来输出对象所属的类型和散列码(hashCode)
  7. arraylist是线程不安全的(多个线程操作同一个ArrayList的时候,可能会出现非期望数据,网上有例子),且在初始化的时候如果,
ArrayList<Object> test = new ArrayList<Object>(100);
test.add(0,new Object);

上述代码会出错,因为这个时候ArrayList的size为0,100只是代表了ArrayList的初始化大小。

  1. 反射

    1)Class类,在程序运行期间,Java运行时系统始终为所有的对象维护一个被称为运行时的类型标识。这个信息保存着每个对象所属的类足迹。虚拟机利用运行时信息选择相应的方法执行方Class.forName(className); 记得弄一个异常捕获。
    常用方法:
    Class.getName(); //获取类名
    object.getName.newInstance(); //可以用来快速创建一个类的实例。
    newInstance()//默认调用对象的无参构造方法;
    newInstance(Object[] args); //构造方法的参数。
    利用反射机制能够打印这个类的相关信息,以及超类等的信息

  2. 可实现多接口,但只能单继承。(多态的概念)

  3. 对象的深拷贝和浅拷贝:
    如果使用 Object o = new Object(“钱”) Object o1 = 0; 这个时候o1和o是引用的同一对象,所以说如果使用o1修改属性值,引用对象的克隆(深拷贝)clone是超类Object中的方法。
    Object o = new Object(“钱”); Object o1 = o.clone(); 如果对象内部是基本数据类型的话,修改不会对彼此产生影响;如果对象的内部属性
    包含其他对象,(如果不是类似于String这样不可变的)则指向的是同一个子对象。(这个时候是浅拷贝)

  4. 内部类
    使用内部类的原因:
    1) 内部类方法可以访问该类定义所在的作用域中的数据,包括私有数据
    2) 内部类可以对同一个包中的其他类隐藏起来
    3) 当想要定义一个回调函数且不想编写大量代码时,使用内部类更加便捷
    分类:
    成员内部类、静态内部类、局部内部类、匿名内部类(事件监听)

  5. 代理:利用代理可以在运行时创建一个实现了一组给定接口的新类。这种功能只有在编译时无法确定需要实现哪个接口时才有必要使用。
    代理类的特性: 代理类是在程序运行过程中创建的,一旦被创建,就变成了常规类,与虚拟机中的任何其他类没有什么区别。
    所有的代理类都扩展于Proxy类,一个代理类只有一个实例变量—调用处理器,它定义在Proxy的超类中。
    为了履行代理对象的职责,所需要的任何附加数据都必须存储在调用处理器中。
    所有的代理类都覆盖了Object类中的方法toString()、equals和hashCode方法。
    在这里插入图片描述

  6. 图形程序设计(AWT、Java Swing)
    在这里插入图片描述
    基本AWT库采用将处理用户界面元素的任务委派给每个目标平台的本地GUI工具箱的方式,由本地GUI工具箱负责用户界面元素的创建和动作。
    Swing 没有完全代替AWT,而是基于AWT架构之上。
    在Java中,顶层窗口(就是没有包含在其他窗口中的窗口)被称为框架。在AWT库中有一个称为Frame的类。用于描述顶层窗口。这个类的Swing版本名为JFame,它扩展与Frame类。JFrame是极少数几个不绘制在画布上的Swing组件之一。因此,它的修饰部件(按钮、标题、图标等)
    在这里插入图片描述
    一个事件源可以发送到多个监听器,多个事件源也可以到一个监听器
    布局管理器:像安卓一样,页面的布局需要页面布局管理器。Java用一个非常出色的概念诗选动态布局:容器内的所有组件都由布局管理器
    进行定位。Java中的默认布局管理器是流布布局管理器。
    流布局管理器的特点是在一行水平排列组件,直到没有足够的空间为止,这时开始新的一行。当用户缩放容器时,布局管理器自动的调整组件的为止使其填充可用的空间。
    为容器设置布局管理器 SetLayout(LayoutMananger m)
    边界布局(BorderLayout),四周不变,缩放的时候改变中间位置的大小。
    网格布局(GridBagLayout)
    箱式布局以及重叠布局等等。

    过滤器: 有文档过滤器(DocumentFilter)和文件过滤器(FileFilter)可以对文档,文本内容、格式以及文件进行扩充校验;
    检测器: 还有另一种潜在的实用机制,它可以用来警告用户以避免无效的输入。可以给任何JComponent附加校验器(verifier).如果组件失去焦点,就询问检验其。如果校验器报告组件中的内容是无效的,组件马上会重获焦点。因为,用户在提供其他输入之前,必须先修正无效的内容。
    校验器必须扩展抽象类InputVerifier,并且定义verify方法。文本域的一个简单检验器。

class MyTextVerifer{
      public boolean verify(JComponent component){
             JFormattedTextField field = (JFormattedTextField) component;
             return field.isEditValid();
       }
      }

然而,检验器并不是万无一失的。如果过点击按钮,按钮会在无效组件重新获得焦点之前通过他的动作监听器。动作监听器就会从验证失败的组件得到无效的结果。
对话框:
与最流行的窗口系统一样,AWT也区分模式对话框和无模式对话框,一个模式对话框在用户结束对它的操作之前,不允许用户与应用程序其余的窗口进行交互。模式对话框用于在程序继续运行之前获取用户提供的信息;无模式对话框允许用户同时在对话框和应用程序其余的窗口中输入信息,一个最好的例子就是工具栏。
选项对话框,Swing具有一组简单的对话框,用于手机用户的一些简单信息。JOptionPane有四个用于显示这些简单的对话框的静态方法:
showMessageDialog 显示一条消息并等待用户点击OK 无
showConfirmDialog 显示一条信息并等待用户确认 代表被选项的一个整数
showOptionDialog 显示一条信息并得到用户在一组选项中的选择 代表被选项的一个整数
showInputDialog 显示一条信息并得到用户的一行输入 用户选择或输入的字符串
每个对话框可以指定一条消息。消息可以是字符串、图标、用户界面组件或者
其他类型的对象(调用toString方法显示结果字符串)

文件对话框:(JFileChooser) 可以无需指定父容器,且可重用
1)调用setCurrentDiectory方法 设置当前目录 chooser.setCurrentDiretory()
2) 默认文件名,setSelectedFile方法进行指定
3)允许选择多个文件,需要调用setMultiSelectionEnable方法
4)如果需要只选择某一类文件,则需要配置文件过滤器
5)在默认情况下,用户在文件选择器中只能选择文件。如果希望选择目录,需要使用
setFileSelectionMode方法:参数为:JFileChooser.FILE_ONLY(默认值)、
JFIleChooser>DIRECTORIES_ONLY或者
JFileChooser.FILES_AND_DIRECTORIES
6) 调用showOpenDialog或者showSavageDialog方法显示对话框。必须为这些调用提供父组件
int result = chooser.showOpenDialog(parent,“选择按钮”);
7)使用getSelectedFile()或者getSelectedFiles()方法来获取得选择的一个或多个文件这些方法将返回一个File对象或者一组FIle对象。如果需要文件对象名字时,可以调用 getPath方法
在这里插入图片描述

8) 文件视图
颜色选择器,例如其他类似的还有日期等等
添加监听器需要提供一个父组件

 chooser.getSelectionModel().addChangeListener( new ChangeListener()
  {
     方法体:
     获取颜色的方法,chooser.getColor();
  }
  });

  1. jar命令(类似于UNIX tar 命令)
    一般打包命令: jar cvf 文件名1 文件名2 …
    1) jar命令选项:
    jar命令格式:jar {c t x u f }[ v m e 0 M i ][-C 目录]文件名…
    其中{ctxu}这四个选项必须选其一。[v f m e 0 M i ]是可选选项,文件名也是必须的。
    -c 创建一个jar包
    -t 显示jar中的内容列表
    -x 解压jar包
    -u 添加文件到jar包中
    -f 指定jar包的文件名
    -v 生成详细的报造,并输出至标准设备
    -m 指定manifest.mf文件.(manifest.mf文件中可以对jar包及其中的内容作一些一设置)
    -0 产生jar包时不对其中的内容进行压缩处理
    -M 不产生所有文件的清单文件(Manifest.mf)。这个参数与忽略掉-m参数的设置
    -i 为指定的jar文件创建索引文件
    -C 表示转到相应的目录下执行jar命令,相当于cd到那个目录,然后不带-C执行jar命令
    在这里插入图片描述
    在这里插入图片描述

  2. java start web
    将程序(图形化的基本上是)打包成jar包,然后添加一个文件名对应的.jnlp文件。放到tomcat的webapp文件下,然后在添加一个index.html文件,内容指向这个jnlp文件,运行tomcat启动成功后,访问index.html文件即可;java web start 暂时未发现他的用处 !

  3. 应用程序的存储
    1)属性映射(property map)是存储键/值对的数据结构。属性映射经常用来存放配置信息
    有三个特性:
    键和值都是字符串;很容易地写入或从文件读取
    使用二级缓存表示存放默认值
    在java平台上,实现属性映射的类称为properties
    Properties settings = new Properties();
    settings.put(“key1”,“value1”);
    可以使用store方法将属性列表保存到文件中。
    FileOutputStream out = new FileOutputStream(“setting.properties”);
    settings.trore(out,“Test properties”); // 第二个参数是包含在该文件中的注释
    从文件中加载属性,可以使用

FileInputStream in = new FileInoutStream(setting.properties);
setting.load(in);

这个东西也是很有用的,比如说通过类加载器,自己主动来加载类时,可以通过这种方式,将类的配置加载进来
properties类继承于Hashtable类,put方法不检查放入表中的值是否是一个字符串。
属性配置文件的优缺点
有点:属性配置文件可以很快的读写的过程
缺点:配置文件不一定和应用程序存储在同一个位置,因为存放的地方可能是不可写的。
例如在一个只读目录下或者是在jar文件中
2)多个用户可能想以不同方式配置同一个应用程序
3) 配置文件不能存放在用户的主目录中,因为某些操作系统(如Windows 9X)没有主目录的概念
没有标准的为配置文件命名的规则,当用户安装了多个java应用程序时,会增加配置文件名字冲突的可能性

Preferences API
能够解决上面的问题,对于没有用户主目录的操作系统,在Windows上通过保存到注册表中来实现
在Linux上通过保存到用户本地来实现

  1. java中的异常:Java语言规范将派生于RuntimeException类或Error类的所有异常称为“未检查异常”,其它异常称为“已检查异常”
    如果子类中重写了超类的一个方法,那么,子类方法中声明的已检查异常不能超过超类方法中,声明的异常范围范围(子类方法中抛出的异常只能更具体,也就是更小,或者不抛出异常)
    自定义异常类,一般应该包含两个构造器,一个是默认构造器,另一个是带有信息信息的构造器
    当捕获到异常时,可以通过 Throwable exception = e.getCause();方法得到原始异常
    关键字,finally :代码没有异常将会执行try中的语句,执行完try中的语句就会执行finally中的语句
    ,接着在执行try外面的语句;
    try 语句可以没有catch语句,这个时候必须有一个finally语句。
    在这里插入图片描述

  2. 日志 :
    日志主要涉及到处理器,过滤器、格式化器
    slf4j或是java.util.loggin
    在这里插入图片描述
    在这里插入图片描述

  3. 断言
    从JDK1.5以后是默认支持断言的,在默认情况下,断言是禁用的。可以在运行程序时使用-enablessertions或-ea选项启用它 : 例如 java - enableassert MyApp需要注意的是,在启用或禁用断言时不必重新编译程序。启用或禁用断言时类加载器的功能。当断言被禁用时,类加载器将跳过断言代码,因此,不会降低程序运行速度。
    也可以在某个类或某个保重使用断言。例如java -ea:MyClass -ea:com.zlc.app
    这条命令将开启MyClass类以及在com.zlc.app包下的所有的断言
    -ea将开启默认包中的所有类的断言
    也可以用选项 -disableassertions 或-da禁用某个特定类和包的断言
    java -ea : … da:MyClass MyApp
    有些类不是由类加载器加载,而是由虚拟机加载的。
    断言只能应用于开发和调试阶段
    不一定只有在异常的时候才可以捕获堆栈信息,可以通过Thead.dumpStack();
    想要观察类的加载过程,可以用 -verifybose标志运行java虚拟机

  4. AWT中的Robot类(可以弄个脚本)
    包含了一些键盘敲击和鼠标点击等获得默认的屏幕设备:

 GraphicsEnvironment environment =   GraphicsEnvironment.getLocalGraphicsEnvironment();
  GraphicsDevice screen = environment.getDefaultScreenDevice();

然后构造一个Robot对象 Robot robot = new Robot(screen);
键盘敲击事件 robot.keyPress(KeyEvent.VK_TAB);
释放 robot.Release(KeyEvent.VK_TAB);
robot.mouseMove(x,y); 鼠标移动,(x,y是绝对屏幕坐标系的像素坐标)
robot.mousePress(InputEnvent.BUTTON1_MASK); 鼠标点击
捕获屏幕截图,给一个矩形框。

  Rectangle rect = new Rectangle(x,y,width,height);
  BufferedImage image = robot.createScreenCapture(rect);

  1. JDB调试器,现在开发工具都有debug功能,知道名字就行。

  2. 流与文件
    在这里插入图片描述
    1)输入流:一个能读取字节序列的对象被称为输入流;一个可以写入字节序列的对象被称为输出流。
    2) InputStream抽象类中的read和write方法都能阻塞一个线程直到字节被正真的读取或者写入,这意味着如果流不能立即读取或写入,Java就会挂起这个调用的线程。这样就能够给其他线程提供机会去做有用的动作,同时这个方法 将一直等待,直到流再次可用为止。当完成流的读取或者写入后,就应该调用close方法关闭它们 ;关闭一个输出流也可以刷新输出流占用的缓存区。
    在这里插入图片描述
    在这里插入图片描述
    skip(long n)方法,跳过n个字节;
    available()方法,返回可用的未阻塞的字节数。
    mark(int readLimit) 在输入流的当前位置放一个标记。(不是所有流都支持这个特性)如果从输入流中读取的字节多于readlimmit字节,那么允许忽略这个标记。
    reset()返回最后的标记。在之后调用read方法时将会重读那些字节。如果目前没有标记,则流将不会被重置。
    markSupported() 如果流支持标记则返回true。
    flush() 刷新输出流,即将缓冲区中的所有数据发送到目的地
    close( ) 刷新并关闭输出流
    FileOutputStream(String name) 新建一个由name指定的文件输出流。路径名不是绝对路径,而是相对于当前的工作路径;(该方法会自动删除存在的同名文件)
    FileOutputStream(String name,boolean append) 新建一个由name字符串指定的文件输出流。路径名不是绝对路径,是相对于当前工作路径,如果append参数为true,则将数据追加到文件的结尾。存在同名的文件不会被 删除。
    FileOutputStream(File f)新建一个使用封装在File对象中的信息的文件输出流,这个方法会自动删除人核已经存在的且与f同名的文件。
    BufferedInputStream(InputStream in) 新建一个默认大小的缓冲流。缓冲的输入流从一个流中读取字符,而不是每次都引起对设备的访问。当缓冲区空时,一个新的数据块将会被读入缓冲区。
    BuffeedInputStream(InputStram in,int n),n指定大小的缓存

  3. 随机存取文件流
    RandomAccessFile流类能够在文件的任何位置查找或者写入数据。它同时实现了DataInput和DataOutput接口。磁盘文件可以随机
    存取,但是来自网络的数据流就不行了。打开一个岁建存取文件,要么进行只读操作,要么进行读写操作。
    可以通过构造器的第二个参数带入“r”“rw”指定相应的操作。当打开一个现有文件作为RandomAccessFile时,原来的文件不会被删除。

RandomAccessFile(String file ,String mode)
RandomAccessFile(File file, String mode)
mode "r"表示只读模式,“rw”表示读/写模式,“rws”表示对于每一次的更新采用同步方式将数据或元数据写入磁盘的读/写模式,“rwd”表示采用同步模式将数据邪恶如磁盘的读/写模式

long getFilepointer() 返回文件指针的当前位置

void seek(Long pos)将文件指针的位置设定为从文件开始的pos字处。

long length() 返回文件的长度(以字节计)

字符集,这个以前看过一篇博客 写的很好

  1. 文本输出

进行文本输出时,应该使用PrintWrite.一个PrintWriter必须与一个目标writer相结合
PrintWriter out= new PrintWriter(new Filewriter(“employee.txt”));
PrintWriter out = new PrintWriter(new FileOutputStream(“employee.txt”));

  1. 文本输入
    当以二进制写入数据时,应当使用DataOutputStream; 当以文本格式写入数据时,应当使用PrintWriter.

  2. ZIP文件流
    每个ZIP文件都有头文件,其中包含了诸如文件名和使用的压缩方法等信息,可以使用ZipInoutStream类读取一个ZIP文件
    ZipInputStream(InputStream in) 这个构造器创建了一个ZipInputStream,它允许从给定的InputStream内读取数据
    ZipEntry getNextEntry() 返回下一条目的ZipEntry对象,如果没有更多的条目的话,返回null
    void closeEntry() 关闭ZIP文件中当前打开的条目。随后可以使用getNextEntry()读取下一条目。

ZipOutputStream(OutputStream out) 这个构造器创建了一个ZipOutputStream内写入压缩数据
void putNextEntry(ZipEntry ze) 将给定的ZipEntry的信息写入流中并且为数据定位流。随后可以使用
write()把数据写入流中。
void closeEntry() 关闭ZIP文件中目前打开的条目。使用putNextEntry方法开始对下一条目进行操作。
void setLevel(int level) 压缩级别,从0(NO_COMPRESSION,即没有压缩)到9(BEST_COMPRESSION,最佳压缩)
void setMethod(int method)对于该ZipOutputStream中的全部没有指定压缩方法的条目,设置默认的压缩方法。
menthod 压缩方法,是DEFLATED或者STORED

  1. StringBuilder类和StringBuffer类
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  2. 对象流(ObjectInputStream/ObjectoutputStream)
    对于任何需要在对象流中存储和恢复的类必须实现Serializable接口,该接口没有方法,所以不需要要对自己的类进行任何修改,和Cloneable接口很相似。然而,要一个类能够被克隆,仍然必须覆盖Object类的clone方法。要让一个类能够序列化,则不需要做其他的任何事。
    void writeObject(Object obj) 将指定的对象写入ObjectOutputStream。这个方法将保存
    对象的类、类的签名以及该类及其超类的非静态、非临时的域的值。
    void readObject()
    在这里插入图片描述
    在这里插入图片描述
  3. 关于序列化和反序列化
    所有的对象(包括数组和字符串)以及类描述符在保存到输出文件时,都会获得一个序列号。因为每个被保存的对象都会分配到一个唯一的序列号(从00 7E 00 00开始),这个处理流程被称为序列化。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  4. 在这里插入图片描述
  5. 在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. 在这里插入图片描述

在这里插入图片描述

文件锁(lock()方法和tryLock()方法)
FlieChannel fileChannel = new FileChannel(“a.txt”);
FileLock lock = lock.lock();
在这里插入图片描述

发布了65 篇原创文章 · 获赞 48 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/chen15369337607/article/details/103252321