Java 高级知识

编程技术  /  houtizong 发布于 3年前   96

Java 的一些高级知识你掌握了吗? 我最近在做一个网络通信的项目,本文中的提到的内容全都使用到了,主要有IO,类加载器,序列化,线程池 等等.这里做一下整理。

 

 

作者:赵磊

博客:http://elf8848.iteye.com

 

--------------------------修饰符------------------------------
java48个修饰符有以下几个不常用的:
不常用到的关键字有:const,goto,native,strictfp,transient,volatile。

其中const和goto为java中的保留字。


transient
序列化的时候不被存储


volatile
弱同步  volatile修饰变量。在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。参见:http://www.ibm.com/developerworks/cn/java/j-jtp06197.html


srticftp
修饰类和方法,意思是FP-strict,精确浮点,符合IEEE-754规范的。当一个class或interface用strictfp声明,内部所有的float和double表达式都会成为strictfp的。


native
   是方法修饰符。Native方法是由另外一种语言(如c/c++,FORTRAN,汇编)实现的本地方法。

 

--------------------线程池-------------------
java.util.concurrent.Executors工具类

此包中所定义的 Executor、ExecutorService、ScheduledExecutorService、ThreadFactory 和 Callable 类的工厂和实用方法。此类支持以下各种方法:

创建并返回设置有常用配置字符串的 ExecutorService 的方法。
创建并返回设置有常用配置字符串的 ScheduledExecutorService 的方法。
创建并返回“包装的”ExecutorService 方法,它通过使特定于实现的方法不可访问来禁用重新配置。
创建并返回 ThreadFactory 的方法,它可将新创建的线程设置为已知的状态。
创建并返回非闭包形式的 Callable 的方法,这样可将其用于需要 Callable 的执行方法中。

创建一个线程池,用来执行定任务。 例子:
http://elf8848.iteye.com/blog/1538673
Executors. newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory)

创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。

Executors. newFixedThreadPool(int nThreads)

创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们,并在需要时使用提供的 ThreadFactory 创建新线程。

Executors. newCachedThreadPool(ThreadFactory threadFactory)

创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。

Executors. newSingleThreadExecutor()

 

----------------------------集合类--------------------------------

 

返回一个只包含指定对象的不可变 List。返回的列表是可序列化的。 其中包含一个obj对象
List<T> list=Collections.<T>singletonList(T obj);

返回一个只包含指定对象的不可变 set。返回的 set 是可序列化的。其中包含一个obj对象

Set<T> set=Collections.<T>singleton(T obj);

返回一个不可变 的映射,它只将指定键映射到指定值。返回的映射是可序列化的。

只包含指定键-值映射关系的不可变映射。
Map(K ,V) map=Collections.<K,V>singletonMap(K key,V value);

 

返回指定有序 set 的不可修改 视图。
SortedSet<T> set=Collections.unmodifiableSortedSet(SortedSet<T> s)

返回指定列表的不可修改 视图。

List<T> list=Collections.unmodifiableList(List<? extends T> list)

返回指定映射的不可修改 视图。

Map<K,V> map=Collections.unmodifiableMap(Map<? extends K,? extends V> m)

 

返回指定列表支持的同步(线程安全的)列表。
List<T>  a=Collections.synchronizedList(List<T> list)

返回由指定映射支持的同步(线程安全的)映射。
Map<K,V>  a=Collections.synchronizedMap(Map<K,V> m)

返回指定 set 支持的同步(线程安全的)set。
Set<T>  a=Collections.synchronizedSet(Set<T> s)

 

---List包含---
如果列表包含指定的元素,则返回 true。
boolean contains(Object o)
        
---Map包含---
如果此映射包含指定键的映射关系,则返回 true。
boolean containsKey(Object key)
          
如果此映射将一个或多个键映射到指定值,则返回 true。
boolean containsValue(Object value)
         
测试此映射表中是否存在与指定值关联的键。(此方法在功能上等同于 containsValue 方法,Hashtable,ConcurrentHashMap中有这个方法)
contains(Object value)
         
---Set包含---
如果 set 包含指定的元素,则返回 true。
boolean contains(Object o)

 

 

 

CopyOnWriteArrayList
CopyOnWriteArraySet
它最适合于具有以下特征的应用程序:
set 大小通常保持很小,只读操作远多于可变操作,需要在遍历期间防止线程间的冲突。
它是线程安全的。
因为通常需要复制整个基础数组,所以可变操作(add、set 和 remove 等等)的开销很大。
迭代器不支持可变 remove 操作。
使用迭代器进行遍历的速度很快,并且不会与其他线程发生冲突。在构造迭代器时,迭代器依赖于不变的数组快照。

 

 

-----------------------------类.this 类 的作用--------------------


this指的是当前正在访问这段代码的对象,当在内部类中使用this指的就是内部类的对象,
为了访问外层类对象,就可以使用外层类名.this来访问,一般也只在这种情况下使用这种

 

----------------------------- 类加载器部分 -----------------------

 

请看:《深入探讨 Java 类加载器》

http://www.ibm.com/developerworks/cn/java/j-lo-classloader/

 

核心节选:

Java 中的类加载器大致可以分成两类,一类是系统提供的,另外一类则是由 Java 应用开发人员编写的。系统提供的类加载器主要有下面三个:

    引导类加载器(bootstrap class loader):它用来加载 Java 的核心库,是用原生代码来实现的,并不继承自 java.lang.ClassLoader。
    扩展类加载器(extensions class loader):它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。
    系统类加载器(system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过 ClassLoader.getSystemClassLoader()来获取它。

类加载器的代理模式

类加载器在尝试自己去查找某个类的字节代码并定义它时,会先代理给其父类加载器,由父类加载器先去尝试加载这个类,依次类推。

线程上下文类加载器

线程上下文类加载器(context class loader)是从 JDK 1.2 开始引入的。类 java.lang.Thread中的方法 getContextClassLoader()和 setContextClassLoader(ClassLoader cl)用来获取和设置线程的上下文类加载器。如果没有通过 setContextClassLoader(ClassLoader cl)方法进行设置的话,线程将继承其父线程的上下文类加载器。Java 应用运行的初始线程的上下文类加载器是系统类加载器。在线程中运行的代码可以通过此类加载器来加载类和资源。

类加载器与 Web 容器


对于运行在 Java EE™容器中的 Web 应用来说,类加载器的实现方式与一般的 Java 应用有所不同。不同的 Web 容器的实现方式也会有所不同。以 Apache Tomcat 来说,每个 Web 应用都有一个对应的类加载器实例。该类加载器也使用代理模式,所不同的是它是首先尝试去加载某个类,如果找不到再代理给父类加载器。这与一般类加载器的顺序是相反的。这是 Java Servlet 规范中的推荐做法,其目的是使得 Web 应用自己的类的优先级高于 Web 容器提供的类。这种代理模式的一个例外是:Java 核心库的类是不在查找范围之内的。这也是为了保证 Java 核心库的类型安全。

----------------------------- 序列化部分 -------------------------

 

 

----------------------------- IO部分 ------------------------------

 

ByteArrayInputStream 数组转流
ByteArrayOutputStream 流转数据,其中的数据被写入一个 byte 数组

StringReader 把String读到Reader

StringWriter 把String写到Write

OutputStreamWriter String转流,是字符流通向字节流的桥梁

InputStreamReader 流转String,是字节流通向字符流的桥梁


CharArrayReader 此类实现一个可用作字符输入流的字符缓冲区。

CharArrayWriter 此类实现一个可用作 Writer 的字符缓冲区。缓冲区会随向流中写入数据而自动增长。可使用 toCharArray() 和 toString() 获取数据。

为了获得最高效率,可考虑将 OutputStreamWriter 包装到 BufferedWriter 中,以避免频繁调用转换器。例如:

Writer out = new BufferedWriter(new OutputStreamWriter(System.out));

为了达到最高效率,可要考虑在 BufferedReader 内包装 InputStreamReader。例如:

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

RandomAccessFile 此类的实例支持对随机访问文件的读取和写入。


FileReader 用来读取字符文件的便捷类。

FilterWriter 用来写入字符文件的便捷类。

FileInputStream 从文件系统中的某个文件中获得输入字节。

FileOutputStream 文件输出流是用于将数据写入 File 或 FileDescriptor 的输出流。

ObjectOutputStream 对象序列化

ObjectInputStream 对象序列化

 

----------------------------- IO部分 文本文件编码------------------------------

 

读取文本文件内容,并正确指定编码

public static void main(String[] args) throws Exception {String path="d:\\计算.txt";File file=new File(path);FileInputStream in=new FileInputStream(file);//文本文件编码是UTF-8,如果是其它,请修改下面InputStreamReader read = new InputStreamReader(in, "UTF-8");BufferedReader ra = new BufferedReader(read);String s=ra.readLine();while(s!=null){System.out.println(s);s=ra.readLine();}}

 

 

写入文本文件,并正确指定编码

final File file = new File("d:\\a.txt");if (!file.exists()){new File(file.getParent()).mkdirs();file.createNewFile(); //文件不存在,建立}final Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));out.write("大量文字内容,比如HTML代码");out.flush();out.close();

 

 

问:用JAVA字符流向硬盘写一个a.txt文件时,默认情况下a.txt会使用什么字符集编码?

答:"字符流"默认用JVM中所设置的字符集编码, JVM是从系统变量file.encoding中读取操作系统的默认编码的字符集,来设置JVM的字符集编码的。

要查看系统的file.encoding参数,可以用以下代码:

 

public static void main(final String[] args) {  final String encoding = System.getProperty("file.encoding");  System.out.println(encoding); }

 

 结果与操作系统(我用MS Windows)的区域语言有关系,如下表

 

标准和格式 JVM默认字符集
中文(中国) GBK
中文(新加坡) GBK
中文(香港特别行政区) MS950
中文(澳门特别行政区) MS950
中文(台湾) MS950

 

 ---------------------------------Java 网络编码解码-----------------------------------------

java.net.URLEncoder
java.net.URLDecoder

try {       String encodeStr = URLEncoder.encode("中国", "utf-8");       System.out.println("处理后:" + encodeStr);       String decodeStr = URLDecoder.decode(encodeStr, "utf-8");       System.out.println("解码:" + decodeStr);   } catch (UnsupportedEncodingException e) {       // TODO Auto-generated catch block       e.printStackTrace();   } 

处理后:%E4%B8%AD%E5%9B%BD   
解码:中国 

 

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!

留言需要登陆哦

技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成

网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];

      订阅博客周刊 去订阅

文章归档

文章标签

友情链接

Auther ·HouTiZong
侯体宗的博客
© 2020 zongscan.com
版权所有ICP证 : 粤ICP备20027696号
PHP交流群 也可以扫右边的二维码
侯体宗的博客