JavaFx疑难杂症汇总

1.webview有些地方中文乱码

原因为不支持宋体,吧css中的宋体给为微软雅黑就好

2.xp下页面被放大,鼠标漂移问题

导致该问题主要是由于启用了3D硬件加速,通过设置系统参数-Dprism.order=j2d解决,注意需要在main中也加入

3.xp下会导致蓝屏问题

在win7下打包的exe在xp下运行会发生这种情况,可以在xp下打包,这样支持xp和win7平台

Java开发exe程序

1.使用JavaFX技术
2.使用NetBeans IDE 7.4,通过build.xml生成exe和jar文件

<?xml version="1.0" encoding="UTF-8"?><!-- You may freely edit this file. See commented blocks below for --><!-- some examples of how to customize the build. --><!-- (If you delete it and reopen the project it will be recreated.) --><!-- By default, only the Clean and Build commands use this build script. --><project name="HelloWorld" default="default" basedir="." xmlns:fx="javafx:com.sun.javafx.tools.ant">
    <description>Builds, tests, and runs the project HelloWorld.</description>
    <import file="nbproject/build-impl.xml"/>
    <!--

    There exist several targets which are by default empty and which can be 
    used for execution of your tasks. These targets are usually executed 
    before and after some main targets. Those of them relevant for JavaFX project are: 

      -pre-init:                 called before initialization of project properties
      -post-init:                called after initialization of project properties
      -pre-compile:              called before javac compilation
      -post-compile:             called after javac compilation
      -pre-compile-test:         called before javac compilation of JUnit tests
      -post-compile-test:        called after javac compilation of JUnit tests
      -pre-jfx-jar:              called before FX SDK specific <fx:jar> task
      -post-jfx-jar:             called after FX SDK specific <fx:jar> task
      -pre-jfx-deploy:           called before FX SDK specific <fx:deploy> task
      -post-jfx-deploy:          called after FX SDK specific <fx:deploy> task
      -pre-jfx-native:           called just after -pre-jfx-deploy if <fx:deploy> runs in native packaging mode
      -post-jfx-native:          called just after -post-jfx-deploy if <fx:deploy> runs in native packaging mode
      -post-clean:               called after cleaning build products

    (Targets beginning with '-' are not intended to be called on their own.)

    Example of inserting a HTML postprocessor after javaFX SDK deployment:

        <target name="-post-jfx-deploy">
            <basename property="jfx.deployment.base" file="${jfx.deployment.jar}" suffix=".jar"/>
            <property name="jfx.deployment.html" location="${jfx.deployment.dir}${file.separator}${jfx.deployment.base}.html"/>
            <custompostprocess>
                <fileset dir="${jfx.deployment.html}"/>
            </custompostprocess>
        </target>

    Example of calling an Ant task from JavaFX SDK. Note that access to JavaFX SDK Ant tasks must be
    initialized; to ensure this is done add the dependence on -check-jfx-sdk-version target:

        <target name="-post-jfx-jar" depends="-check-jfx-sdk-version">
            <echo message="Calling jar task from JavaFX SDK"/>
            <fx:jar ...>
                ...
            </fx:jar>
        </target>

    For more details about JavaFX SDK Ant tasks go to

http://docs.oracle.com/javafx/2/deployment/jfxpub-deployment.htm

    For list of available properties check the files
    nbproject/build-impl.xml and nbproject/jfx-impl.xml.

    -->
    
    <target name="-post-jfx-deploy">
       <fx:deploy width="${javafx.run.width}" height="${javafx.run.height}" 
                  nativeBundles="all"
                  outdir="${basedir}/${dist.dir}" outfile="${application.title}">
          <fx:application name="${application.title}" 
                          mainClass="${javafx.main.class}"/>
          <fx:resources>
              <fx:fileset dir="${basedir}/${dist.dir}"
                          includes="*.jar"/>
          </fx:resources>
          <fx:info title="${application.title}" 
                   vendor="${application.vendor}"/>
        </fx:deploy>          
     </target>
</project>

HelloWorld.java



import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
 
 
public class HelloWorld extends Application {
    private Scene scene;
    @Override public void start(Stage stage) {
        // create the scene
        stage.setTitle("Web View");
        scene = new Scene(new Browser(),1280,800, Color.web("#666970"));
        stage.setScene(scene);
        //scene.getStylesheets().add("webviewsample/BrowserToolbar.css");        
        stage.show();
    }
 
    public static void main(String[] args){
        launch(args);
    }
}
class Browser extends Region {
 
    final WebView browser = new WebView();
    final WebEngine webEngine = browser.getEngine();
     
    public Browser() {
        //apply the styles
        getStyleClass().add("browser");
        // load the web page
        webEngine.load("http://chrome.360.cn/test/html5/index.html");
        //add the web view to the scene
        getChildren().add(browser);
 
    }
    private Node createSpacer() {
        Region spacer = new Region();
        HBox.setHgrow(spacer, Priority.ALWAYS);
        return spacer;
    }
 
    @Override protected void layoutChildren() {
        double w = getWidth();
        double h = getHeight();
        layoutInArea(browser,0,0,w,h,0, HPos.CENTER, VPos.CENTER);
    }
 
    @Override protected double computePrefWidth(double height) {
        return 750;
    }
 
    @Override protected double computePrefHeight(double width) {
        return 500;
    }
}

3.生成后使用Inno Setup Compiler打包成安装程序,需要include NetBeansProjects\HelloWorld\dist\bundles\HelloWorld下的文件
包括jre运行环境和jar配置

DONE!

quartz 时间配置规则

很久没用弄QUARTZ了,它的规则都忘记了,今天用到就找了篇别人的文章,这里记录下

格式: [秒] [分] [小时] [日] [月] [周] [年]

序号 说明 是否必填 允许填写的值 允许的通配符
1 0-59 , – * /
2 0-59 , – * /
3 小时 0-23 , – * /
4 1-31 , – * ? / L W
5 1-12 or JAN-DEC , – * /
6 1-7 or SUN-SAT , – * ? / L #
7 empty 或 1970-2099 , – * /

通配符说明:
* 表示所有值. 例如:在分的字段上设置 “*”,表示每一分钟都会触发。
? 表示不指定值。使用的场景为不需要关心当前设置这个字段的值。例如:要在每月的10号触发一个操作,但不关心是周几,所以需要周位置的那个字段设置 为”?” 具体设置为 0 0 0 10 * ?
- 表示区间。例如 在小时上设置 “10-12″,表示 10,11,12点都会触发。
, 表示指定多个值,例如在周字段上设置 “MON,WED,FRI” 表示周一,周三和周五触发
/ 用于递增触发。如在秒上面设置”5/15″ 表示从5秒开始,每增15秒触发(5,20,35,50)。 在月字段上设置’1/3’所示每月1号开始,每隔三天触发一次。
L 表示最后的意思。在日字段设置上,表示当月的最后一天(依据当前月份,如果是二月还会依据是否是润年[leap]), 在周字段上表示星期六,相当于”7″或”SAT”。如果在”L”前加上数字,则表示该数据的最后一个。例如在周字段上设置”6L”这样的格式,则表示“本 月最后一个星期五”
W 表示离指定日期的最近那个工作日(周一至周五). 例如在日字段上设置”15W”,表示离每月15号最近的那个工作日触发。如果15号正好是周六,则找最近的周五(14号)触发, 如果15号是周未,则找最近的下周一(16号)触发.如果15号正好在工作日(周一至周五),则就在该天触发。如果指定格式为 “1W”,它则表示每月1号往后最近的工作日触发。如果1号正是周六,则将在3号下周一触发。(注,”W”前只能设置具体的数字,不允许区间”-“).

小提示 ‘L’和 ‘W’可以一组合使用。如果在日字段上设置”LW”,则表示在本月的最后一个工作日触发(一般指发工资 )

# 序号(表示每月的第几个周几),例如在周字段上设置”6#3″表示在每月的第三个周六.注意如果指定”#5″,正好第五周没有周六,则不会触发该配置(用 在母亲节和父亲节再合适不过了)

小提示 周字段的设置,若使用英文字母是不区分大小写的 MON 与mon相同.

常用示例:

0 0 12 * * ? 每天12点触发
0 15 10 ? * * 每天10点15分触发
0 15 10 * * ? 每天10点15分触发
0 15 10 * * ? * 每天10点15分触发
0 15 10 * * ? 2005 2005年每天10点15分触发
0 * 14 * * ? 每天下午的 2点到2点59分每分触发
0 0/5 14 * * ? 每天下午的 2点到2点59分(整点开始,每隔5分触发)
0 0/5 14,18 * * ? 每天下午的 2点到2点59分(整点开始,每隔5分触发)
每天下午的 18点到18点59分(整点开始,每隔5分触发)
0 0-5 14 * * ? 每天下午的 2点到2点05分每分触发
0 10,44 14 ? 3 WED 3月分每周三下午的 2点10分和2点44分触发
0 15 10 ? * MON-FRI 从周一到周五每天上午的10点15分触发
0 15 10 15 * ? 每月15号上午10点15分触发
0 15 10 L * ? 每月最后一天的10点15分触发
0 15 10 ? * 6L 每月最后一周的星期五的10点15分触发
0 15 10 ? * 6L 2002-2005 从2002年到2005年每月最后一周的星期五的10点15分触发
0 15 10 ? * 6#3 每月的第三周的星期五开始触发
0 0 12 1/5 * ? 每月的第一个中午开始每隔5天触发一次
0 11 11 11 11 ? 每年的11月11号 11点11分触发(光棍节)

 

JSON与JAVA数据的转换

JSON-lib这个Java类包用于把bean,map和XML转换成JSON并能够把JSON转回成bean和DynaBean。

下载地址:http://json-lib.sourceforge.net/
还要需要的第3方包:
org.apache.commons(3.2以上版本)
org.apache.oro
net.sf.ezmorph(ezmorph-1.0.4.jar)
nu.xom

1、List

Java代码
  1. boolean[] boolArray = new boolean[]{true,false,true};
  2. JSONArray jsonArray1 = JSONArray.fromObject( boolArray );
  3. System.out.println( jsonArray1 );
  4. // prints [true,false,true]
  5. List list = new ArrayList();
  6. list.add( “first” );
  7. list.add( “second” );
  8. JSONArray jsonArray2 = JSONArray.fromObject( list );
  9. System.out.println( jsonArray2 );
  10. // prints [“first”,”second”]
  11. JSONArray jsonArray3 = JSONArray.fromObject( “[‘json’,’is’,’easy’]” );
  12. System.out.println( jsonArray3 );
  13. // prints [“json”,”is”,”easy”]

2、Map

Java代码
  1. Map map = new HashMap();
  2. map.put( “name”“json” );
  3. map.put( “bool”, Boolean.TRUE );
  4. map.put( “int”new Integer(1) );
  5. map.put( “arr”new String[]{“a”,“b”} );
  6. map.put( “func”“function(i){ return this.arr[i]; }” );
  7. JSONObject json = JSONObject.fromObject( map );
  8. System.out.println( json );
  9. //{“func”:function(i){ return this.arr[i]; },”arr”:[“a”,”b”],”int”:1,”name”:”json”,”bool”:true}

3、BEAN

Java代码
  1. /**
  2. * Bean.java
  3. private String name = “json”;
  4. private int pojoId = 1;
  5. private char[] options = new char[]{‘a’,’f’};
  6. private String func1 = “function(i){ return this.options[i]; }”;
  7. private JSONFunction func2 = new JSONFunction(new String[]{“i”},”return this.options[i];”);
  8. */
  9. JSONObject jsonObject = JSONObject.fromObject( new JsonBean() );
  10. System.out.println( jsonObject );
  11. //{“func1″:function(i){ return this.options[i]; },”pojoId”:1,”name”:”json”,”options”:[“a”,”f”],”func2″:function(i){ return this.options[i]; }}

4、BEANS

Java代码
  1. /**
  2. * private int row ;
  3. private int col ;
  4. private String value ;
  5. *
  6. */
  7. List list = new ArrayList();
  8. JsonBean2 jb1 = new JsonBean2();
  9. jb1.setCol(1);
  10. jb1.setRow(1);
  11. jb1.setValue(“xx”);
  12. JsonBean2 jb2 = new JsonBean2();
  13. jb2.setCol(2);
  14. jb2.setRow(2);
  15. jb2.setValue(“”);
  16. list.add(jb1);
  17. list.add(jb2);
  18. JSONArray ja = JSONArray.fromObject(list);
  19. System.out.println( ja.toString() );
  20. //[{“value”:”xx”,”row”:1,”col”:1},{“value”:””,”row”:2,”col”:2}]

5、String to bean

Java代码
  1. String json = “{name=\”json\”,bool:true,int:1,double:2.2,func:function(a){ return a; },array:[1,2]}”;
  2. JSONObject jsonObject = JSONObject.fromString(json);
  3. Object bean = JSONObject.toBean( jsonObject );
  4. assertEquals( jsonObject.get( “name” ), PropertyUtils.getProperty( bean, “name” ) );
  5. assertEquals( jsonObject.get( “bool” ), PropertyUtils.getProperty( bean, “bool” ) );
  6. assertEquals( jsonObject.get( “int” ), PropertyUtils.getProperty( bean, “int” ) );
  7. assertEquals( jsonObject.get( “double” ), PropertyUtils.getProperty( bean, “double” ) );
  8. assertEquals( jsonObject.get( “func” ), PropertyUtils.getProperty( bean, “func” ) );
  9. List expected = JSONArray.toList( jsonObject.getJSONArray( “array” ) );
  10. assertEquals( expected, (List) PropertyUtils.getProperty( bean, “array” ) );
Java代码
  1. String json = “{\”value\”:\”xx\”,\”row\”:1,\”col\”:1}”;
  2. JSONObject jsonObject = JSONObject.fromString(json);
  3. JsonBean2 bean = (JsonBean2) JSONObject.toBean( jsonObject, JsonBean2.class );
  4. assertEquals( jsonObject.get( “col” ),new Integer( bean.getCol())   );
  5. assertEquals( jsonObject.get( “row” ), new Integer( bean.getRow() ) );
  6. assertEquals( jsonObject.get( “value” ), bean.getValue() );

6 json to xml
1)
JSONObject json = new JSONObject( true );
String xml = XMLSerializer.write( json );

<o null=”true”>

2)
JSONObject json = JSONObject.fromObject(“{\”name\”:\”json\”,\”bool\”:true,\”int\”:1}”);
String xml = XMLSerializer.write( json );
<o>
<name type=”string”>json</name>
<bool type=”boolean”>true</bool>
<int type=”number”>1</int>
</o>
<o>
<name type=”string”>json</name>
<bool type=”boolean”>true</bool>
<int type=”number”>1</int>
</o>
3)
JSONArray json = JSONArray.fromObject(“[1,2,3]”);
String xml = XMLSerializer.write( json );
<a>
<e type=”number”>1</e>
<e type=”number”>2</e>
<e type=”number”>3</e>
</a>

7 、xml to json
<a>
<e type=”function” params=”i,j”>
return matrix[i][j];
</e>
</a>
<a>
<e type=”function” params=”i,j”>
return matrix[i][j];
</e>
</a>

JSONArray json = (JSONArray) XMLSerializer.read( xml );
System.out.println( json );
// prints [function(i,j){ return matrix[i][j]; }]

 

对象的序列化和反序列化

当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。

把Java对象转换为字节序列的过程称为对象的序列化

把字节序列恢复为Java对象的过程称为对象的反序列化

对象的序列化主要有两种用途:

1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;

2) 在网络上传送对象的字节序列。

一. JDK类库中的序列化API

java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。

java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。、

只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable接口继承自Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以采用默认的序列化方式 。

对象序列化包括如下步骤:

1) 创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;

2) 通过对象输出流的writeObject()方法写对象。

对象反序列化的步骤如下:

1) 创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;

2) 通过对象输入流的readObject()方法读取对象。

下面让我们来看一个对应的例子,类的内容如下:

import java.io.*;

import java.util.Date;

/**

* 对象的序列化和反序列化测试类.

* @author <a href=”mailto:xiexingxing1121@126.com”>AmigoXie</a>

* @version 1.0

* Creation date: 2007-9-15 – 下午21:45:48

*/

public class ObjectSaver {

/**

* @param args

* @author <a href=”mailto:xiexingxing1121@126.com”>AmigoXie</a>

* Creation date: 2007-9-15 – 下午21:45:37

*/

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

ObjectOutputStream out = new ObjectOutputStream

(new FileOutputStream(“D:””objectFile.obj”));

//序列化对象

Customer customer = new Customer(“阿蜜果”, 24);

out.writeObject(“你好!”);

out.writeObject(new Date());

out.writeObject(customer);

out.writeInt(123); //写入基本类型数据

out.close();

//反序列化对象

ObjectInputStream in = new ObjectInputStream

(new FileInputStream(“D:””objectFile.obj”));

System.out.println(“obj1=” + (String) in.readObject());

System.out.println(“obj2=” + (Date) in.readObject());

Customer obj3 = (Customer) in.readObject();

System.out.println(“obj3=” + obj3);

int obj4 = in.readInt();

System.out.println(“obj4=” + obj4);

in.close();

}

}

class Customer implements Serializable {

private String name;

private int age;

public Customer(String name, int age) {

this.name = name;

this.age = age;

}

public String toString() {

return “name=” + name + “, age=” + age;

}

}

输出结果如下:

obj1=你好!

obj2=Sat Sep 15 22:02:21 CST 2007

obj3=name=阿蜜果, age=24

obj4=123

因此例比较简单,在此不再详述。

二.实现Serializable接口

ObjectOutputStream只能对Serializable接口的类的对象进行序列化。默认情况下,ObjectOutputStream按照默认方式序列化,这种序列化方式仅仅对对象的非transient的实例变量进行序列化,而不会序列化对象的transient的实例变量,也不会序列化静态变量。

当ObjectOutputStream按照默认方式反序列化时,具有如下特点:

1)              如果在内存中对象所属的类还没有被加载,那么会先加载并初始化这个类。如果在classpath中不存在相应的类文件,那么会抛出ClassNotFoundException;

2)              在反序列化时不会调用类的任何构造方法。

如果用户希望控制类的序列化方式,可以在可序列化类中提供以下形式的writeObject()和readObject()方法。

private void writeObject(java.io.ObjectOutputStream out) throws IOException

private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;

当ObjectOutputStream对一个Customer对象进行序列化时,如果该对象具有writeObject()方法,那么就会执行这一方法,否则就按默认方式序列化。在该对象的writeObjectt()方法中,可以先调用ObjectOutputStream的defaultWriteObject()方法,使得对象输出流先执行默认的序列化操作。同理可得出反序列化的情况,不过这次是defaultReadObject()方法。

有些对象中包含一些敏感信息,这些信息不宜对外公开。如果按照默认方式对它们序列化,那么它们的序列化数据在网络上传输时,可能会被不法份子窃取。对于这类信息,可以对它们进行加密后再序列化,在反序列化时则需要解密,再恢复为原来的信息。

默认的序列化方式会序列化整个对象图,这需要递归遍历对象图。如果对象图很复杂,递归遍历操作需要消耗很多的空间和时间,它的内部数据结构为双向列表。

在应用时,如果对某些成员变量都改为transient类型,将节省空间和时间,提高序列化的性能。

三. 实现Externalizable接口

Externalizable接口继承自Serializable接口,如果一个类实现了Externalizable接口,那么将完全由这个类控制自身的序列化行为。Externalizable接口声明了两个方法:

public void writeExternal(ObjectOutput out) throws IOException

public void readExternal(ObjectInput in) throws IOException , ClassNotFoundException

前者负责序列化操作,后者负责反序列化操作。

在对实现了Externalizable接口的类的对象进行反序列化时,会先调用类的不带参数的构造方法,这是有别于默认反序列方式的。如果把类的不带参数的构造方法删除,或者把该构造方法的访问权限设置为private、默认或protected级别,会抛出java.io.InvalidException: no valid constructor异常。

四. 可序列化类的不同版本的序列化兼容性

凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量:

private static final long serialVersionUID;

以上serialVersionUID的取值是Java运行时环境根据类的内部细节自动生成的。如果对类的源代码作了修改,再重新编译,新生成的类文件的serialVersionUID的取值有可能也会发生变化。

类的serialVersionUID的默认值完全依赖于Java编译器的实现,对于同一个类,用不同的Java编译器编译,有可能会导致不同的serialVersionUID,也有可能相同。为了提高哦啊serialVersionUID的独立性和确定性,强烈建议在一个可序列化类中显示的定义serialVersionUID,为它赋予明确的值。显式地定义serialVersionUID有两种用途:

1)              在某些场合,希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有相同的serialVersionUID;

2)              在某些场合,不希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有不同的serialVersionUID。

 

JAVA IO流小结

回调(又称为callback):可以理解为一个接口提供一些方法给其他类用,但同时其他类在调用它时,它又调用其他类给它的条件(重写)。

单独一个随机访问文件类: RondomAccessFile类允许随机访问文件同时拥有读和写的功能。
其中方法: close(),read(),writer(),seek(),getFilePointer()这需要注意:这是在有seek()前提下。
流:

一.I/O 流(java 如何实现与外界数据的交流)

流定义:

任何有能力产出数据的数据源对象或者有能力接收数据的数据源对象。他屏蔽了实际的I/O设备处理数据的细节.

1.Input/Output:指跨越出了JVM 的边界,与外界数据的源头或者目标数据源进行数据交换。

2.流的分类

按流向分为输入流和输出流;

按传输单位分为字节流(Stream)结尾的和字符流(Reader和Writer);

按功能还可以分为节点流和过滤流。

节点流:负责数据源和程序之间建立连接;(相当于裸枪)

过滤流:用于给节点增加功能。(相当于功能零部件)

过滤流的构造方式是以其他流位参数构造(这样的设计模式称为装饰模式)。

注:I/O流是一类很宝贵的资源,使用完后必须调用close()方法关闭流并释放资源。在关闭流时只用关闭最外层的流。

3.File 类(java.io.*)可表示一个文件,也有可能是一个目录(在JAVA 中文件和目录都属于这个类中,而且区分不是非常的明显

4.Java.io 下的方法是对磁盘上的文件进行磁盘操作,但是无法读取文件的内容。
注意:创建一个文件对象和创建一个文件在JAVA 中是两个不同的概念。前者是在虚拟机中创建了一个文件,但却并没有将它真正地创建到OS 的文件系统中,随着虚拟机的关闭,这个创建的对象也就消失了。
而创建一个文件才是在系统中真正地建立一个文件。

二.File类:

我们猛看起来像是文件,其实他也可以指代一个文件集,当作为文件集时我们可以对此调用List方法。

这个类的常用构造有:File(“路径”),File(“前边路径”,“后边路径”)File(File,“路径”)

这个类的常用方法:exists(),delete(),getName(),getPath(),isDirectory(),isFile(),length(),
listFile(FileFilter),主要用来过滤文件这里有(可以用来嵌套内部类)mkdir(),mkdirs(),toString(),
FileFilter接口只有accept方法,其返回值为Boolean型,可以在其里边写一些正则表达式来对文件进行筛选。这里需要注意的是传入accept的参数必须是final类型(匿名内部类的要求),这样他才能使用该类范围之外的队像。

顺便讲讲:内部类优点 高聚拢性,缺点在于不易阅读,谨慎使用。

三. 字节流:

InputStream/OutputStream 所有输入输入流的父类,是抽象类。

子类有:

FileInputStream/FileOutputStream(节点流)(注意FileInputStream(path名,boolean)Boolean为true 表示拼接)

DataInputStream/DataOutputStream 数据输入流允许应用程序以与”机器无关方式”从底层输入流中读取基本 Java 数据类型 (8种基本类型,加一种String)读入写出时类型必须一致

BufferedInputStream/BufferedOutputStream 字节缓冲流 用于给节点流增加一个缓冲的功能。(典型的牺牲空间换时间)

1.字节输入流:io包中的InputStream为所有字节输入流的父类。

Int read();读入一个字节(每次一个);

可先使用new byte[]=数组,调用read(byte[] b)

read (byte[])返回值可以表示有效数;read (byte[])返回值为-1 表示结束。

2.在流中close()方法由程序员控制。因为输入输出流已经超越了JVM的边界,所以有时可能无法回收资源。

原则:凡是跨出虚拟机边界的资源都要求程序员自己关闭,不要指望垃圾回收。

四、字节流的字符编码:

字符编码把字符转换成数字存储到计算机中,按ASCii 将字母映射为整数。
把数字从计算机转换成相应的字符的过程称为解码。
乱码的根源在于编解码方式不统一。在世界上任何一种编码方式中都会向上兼容ASCII码。所以英文没有乱码。
编码方式的分类:
ASCII(数字、英文):1 个字符占一个字节(所有的编码集都兼容ASCII)
ISO8859-1(欧洲):1 个字符占一个字节
GB-2312/GBK:1 个字符占两个字节。GB代表国家标准。
GBK是在GB-2312上增加的一类新的编码方式,也是现在最常用的汉字编码方式。
Unicode: 1 个字符占两个字节(网络传输速度慢)
UTF-8:变长字节,对于英文一个字节,汉字三个字节。
原则:保证编解码方式的统一,才能不至于出现错误。
I/O学习种常范的两个错误 1。忘了加flush2.没有加换行。

五。字符流

Reader/Writer所有字符流的父类

其子类有

InputStreamReader/OutputStreamWriter 称为从字节流到字符流的桥转换类。这个类可以设定字符转换方式

FileReader/FileWriter (FileInputStream/FileOutputStream和InputStreamReader/OutputStreamWriter)的组合,只能是本地默认编码

Bufferedreader/BufferedWriter 字符缓冲流,其特有方法readLine()读取一个文本行,newLine()表示Writer到下一个文本行

六 。
一.对象序列化
1. 定义:把一个对象通过I/O流写到文件(持久性介质)上的过程叫做对象的序列化。
2. 序列化接口:Serializable
此接口没有任何的方法,这样的接口称为标记接口。
3. 不是所有对象都能序列化的,只有实现了Serializable的类,他的实例对象才是可序列化的。
4. 在Java种定义了一套序列化规范,对象的编码和解码方式都是已经定义好的。
5. class ObjectOutputStream 和ObjectInputStream也是过滤流,使节点流直接获得输出对象。
ganbin@tarena.com.cn
最有用的方法:
(1)writeObject(Object b)
(2)readObject();该方法返回的是读到的一个对象,但是需要我们注意的是,该方法不会以返回null表示读到文件末尾。
而是当读到文件末尾时会抛出一个IOException;
6. 序列化一个对象并不一定会序列化该对象的父类对象
7. 瞬间属性(临时属性)不参与序列化过程。
8. 所有属性必须都是可序列化的,特别是当有些属性本身也是对象的时候,要尤其注意这一点。序列化的集合就要求集合中的每一个元素都是可序列化的。
9. 用两次序列化把两个对象写到文件中去(以追加的方式),
和用一次序列化把两个对象写进文件的大小是不一样的。
因为每次追加时都会要在文件中加入一个开始标记和结束标记。所以对于对象的序列化不能以追加的方式写到文件中。

URL有空格问题处理

URL mUrl = getClass().getClassLoader().getResource(subDir)

File file = new File(mUrl.getPath());

返回有空格的地址时候去出现问题的。

 

处理方法:

URI mUri =  getClass().getClassLoader().getResource(subDir).toURI();

File file = new File(mUri.getPath());

这样需要对URISyntaxException异常进行处理

静态内部类

静态内部类

静态内部类定义在类中,任何方法外,用static定义。

静态内部类只能访问外部类的静态成员。

生成(new)一个静态内部类不需要外部类成员:这是静态内部类和成员内部类的区别。

静态内部类的对象可以直接生成:  Outer.Inner in=new Outer.Inner();  而不需要通过生成外部类对象来生成。

这样实际上使静态内部类成为了一个顶级类。

静态内部类不可用private来进行定义

注意:当类与接口(或者是接口与接口)发生方法命名冲突的时候,此时必须使用内部类来实现。

用接口不能完全地实现多继承,用接口配合内部类才能实现真正的多继承。

例子:  对于两个类,拥有相同的方法:
class People  {  run();  }

interface Machine{  run();  }

此时有一个robot类:

class Robot extends People implement Machine.  此时run()不可直接实现。

interface Machine  {  void run();  }

class Person  {  void run(){System.out.println(“run”);}  }

class Robot extends Person  {

private class MachineHeart implements Machine  {

publicvoid run(){System.out.println(“heart run”);}

}

publicvoid run(){System.out.println(“Robot run”);}

Machine getMachine(){returnnew MachineHeart();}

}

class Test  {

publicstaticvoid main(String[] args)  {

Robot robot=new Robot();

Machine m=robot.getMachine();

m.run();

robot.run();

}

}

PS:
java中的静态类只存在其内部类中。
为什么会有内部静态类的存在?
因为非静态内部类只能声明非静态成员或方法,而静态内部类则可拥有静态的成员和方法。
但静态内部类中只能引用其外部类的静态成员或变量。因为内部静态类并不与外部类对象关联。
此外,内部类的继承与接口与外部类独立,解决了多继承的问题。
PS1:

内部类的作用:

1、隐藏你不想让别人知道的操作,也即封装性。

2、一个内部类对象可以访问创建它的外部类对象的内容,甚至包括私有变量!
内部类的功能在于,每个内部类都能独立的继承一个接口的实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。内部类使得多重继承的解决方案变得完整,并且内部类允许继承多个非接口类型(类或抽象类)。通过内部类分别继承一个基类,外部类创建内部类的对象,并使用内部类的方法,变相地实现了多继承。
java内部类有什么好处?为什么需要内部类?
1、举一个简单的例子,如果你想实现一个接口,但是这个接口中的一个方法和你构想的这个类中的一个方法的名称,参数相同,你应该怎么办?这时候,你可以建一个内部类实现这个接口。由于内部类对外部类的所有内容都是可访问的,所以这样做可以完成所有你直接实现这个接口的功能。

2、真正的原因是这样的,java中的内部类和接口加在一起,可以解决常被C++程序员抱怨java中存在的一个问题:没有多继承。实际上,C++的多继承设计起来很复杂,而java通过内部类加上接口,可以很好的实现多继承的效果。

静态内部类和非静态内部类的区别
1、和非静态内部类相比,区别就在于静态内部类没有了指向外部的引用。
2、在任何非静态内部类中,都不能有静态数据,静态方法或者又一个静态内部类(内部类的嵌套可以不止一层)。不过静态内部类中却可以拥有这一切。

内部类在封装类被继承时候

首先来看下一下两个类

/*
* @(#)Parant.java    Created on 2011-11-22
* Copyright (c) 2011 ZDSoft Networks, Inc. All rights reserved.
* $Id$
*/
package com.innerextend.www;

/**
* @author gex
* @version $Revision: 1.0 $, $Date: 2011-11-22 下午04:13:21 $
*/
public class Parant {

protected class ParantInner {

public void parantInnerPrint() {
System.out.println("parantInnerPrint");
}
}
}

 


/*
* @(#)Child.java    Created on 2011-11-22
* Copyright (c) 2011 ZDSoft Networks, Inc. All rights reserved.
* $Id$
*/
package com.innerextend.www;

/**
* @author gex
* @version $Revision: 1.0 $, $Date: 2011-11-22 下午04:20:04 $
*/
public class Child extends Parant {

/**
* @param args
*/
public static void main(String[] args) {
Child c = new Child();
c.childPrint();

}

// 这里注释去掉,会调用这个内部类而不是父类的内部类
// private class ParantInner {
//
// public void parantInnerPrint() {
// System.out.println("childInnerPrint");
// }
// }

public void childPrint() {
ParantInner pi = new ParantInner();
pi.parantInnerPrint();
}

}

我们注意一点,Parent和Child类都在同一个包下,所以在child类中new ParantInner();调用默认的构造函数

 

/**
* 注意这里没有权限修饰,也就是说包内可见,当然也要看子类的修饰以及本来的修饰,取最小的就得了
*/
ParantInner(){
}

 

这样运行下来,本程序没有问题。

但是,如果Parent和Child类不在同一个包下,在child类中new ParantInner()时就会包构造函数不可见,没法子创建,因为不同包下,默认构造函数没法继续下去。

解决方法:

1.在ParantInner内部类中自己创建一个public或则protected的构造函数。

2.就是把父类 子类都放到同个包下了。

ps:一般情况下都是第一种方式来处理。

.properties乱码解决

messages_zh_CN.properties编码格式为utf-8,

但是始终运行出来的是乱码

后来经过java转码工具:D:\test>native2ascii -encoding utf-8 messages_zh_CN.properties

messages_zh_CN_c.properties

将messages_zh_CN.properties内容:

 

register_userId_error_key = 用户名不能为空,必须由字母、数字、下划线构成,且长度在[4,10]范围内

register_password_error_key = 密码不能为空,必须由字母、数字、下划线构成,长度在[4,10]范围内,且不能同用户名相同

register_passwordConfirm_error_key = 密码验证必须和密码一致

register_phone_error_key = 电话必须由数字组成,长度在[7,11]范围内

register_email_error_key = email必须合法

register_address_error_key = 地址长度必须在[4,40]范围内

转化为:
register_userId_error_key = \u7528\u6237\u540d\u4e0d\u80fd\u4e3a\u7a7a\uff0c\u5fc5\u987b\u7531\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u4e0b\u5212\u7ebf\u6784\u6210,\u4e14\u957f\u5ea6\u5728[4,10]\u8303\u56f4\u5185
register_password_error_key = \u5bc6\u7801\u4e0d\u80fd\u4e3a\u7a7a\uff0c\u5fc5\u987b\u7531\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u4e0b\u5212\u7ebf\u6784\u6210,\u957f\u5ea6\u5728[4,10]\u8303\u56f4\u5185\uff0c\u4e14\u4e0d\u80fd\u540c\u7528\u6237\u540d\u76f8\u540c
register_passwordConfirm_error_key = \u5bc6\u7801\u9a8c\u8bc1\u5fc5\u987b\u548c\u5bc6\u7801\u4e00\u81f4
register_phone_error_key = \u7535\u8bdd\u5fc5\u987b\u7531\u6570\u5b57\u7ec4\u6210,\u957f\u5ea6\u5728[7,11]\u8303\u56f4\u5185
register_email_error_key = email\u5fc5\u987b\u5408\u6cd5
register_address_error_key = \u5730\u5740\u957f\u5ea6\u5fc5\u987b\u5728[4,40]\u8303\u56f4\u5185
即可正常显示了