先注明:www.json.org/json-zh.html
java和javascript之间的格式转换
string | <=> | java.lang.String, java.lang.Character, char |
number | <=> | java.lang.Number, byte, short, int, long, float, double |
true|false | <=> | java.lang.Boolean, boolean |
null | <=> | null |
function | <=> | net.sf.json.JSONFunction |
array | <=> | net.sf.json.JSONArray (object, string, number, boolean, function) |
object | <=> | net.sf.json.JSONObject |
json-lib jar包需要的依赖包
http://json-lib.sourceforge.net/dependencies.html官方的依赖包说明
JSON建构于两种结构:
- “名称/值”对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。
- 值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)。
JSONObject 与 JSONArray练习
String jsonStr = "{\"derek\":23,\"dad\":49,\"mom\":45}";
//通过fromObject转换json字符串 - JSONObject
JSONObject json = JSONObject.fromObject(jsonStr);
System.out.println(json);
{"derek":23,"dad":49,"mom":45}
直接输出,源字符串已经是满足JSON规范的,准换后还是JSON格式
Map<String,Object> map = new LinkedHashMap<>();
map.put("derek","23");
map.put("dad", "49");
map.put("mom", "45");
//通过fromObject转换Map对象 - JSONObject
JSONObject json2 = JSONObject.fromObject(map);
System.out.println(json2);
{"derek":"23","dad":"49","mom":"45"}
Map属于键值对,所以用JSONObject转换便可以(JSONArray转换就错了,下边有例子将JSONObject转List的错误示范)
//通过构造函数创建JSONObject对象 - JSONObject
JSONObject json1 = new JSONObject();
json1.put("1", "1");
System.out.println(json1);
{"1":"1"}
JSONObject的直接类似Map,直接put,内容已经是json格式的字符串了
List<Map<String, Object>> list = new LinkedList<>();
list.add(map);
System.out.println(JSONObject.fromObject(list));
net.sf.json.JSONException: 'object' is an array. Use JSONArray instead
JSONObject也就不能转换list数据。和JSON的结构说明一致,有序列表javascript解释为array
//通过fromObject转换List - JSONArray
System.out.println(JSONArray.fromObject(list));
[{"derek":"23","dad":"49","mom":"45"}]
JSONArray转换的序列都是以[]包裹的内容,这里Map是键值对,所以继续保存键值效果。
//通过构造函数创建JSONArray对象 - JSONArray
JSONArray json4 = new JSONArray();
json4.add(0,"derek");
json4.add(1,"dad");
json4.add(2,"mom");
System.out.println(json4);
["derek","dad","mom"]
JSONArray对象添加的内容都是单独的字符串,参考add函数
public void add(int index, Object value)
{
add(index, value, new JsonConfig());
}
index只是索引,所以其实他们都是数组,即使上边的转换Map的JSONArray,一个Map作为一个数组对象。
String jsonStr = "{\"derek\":23,\"dad\":49,\"mom\":45}";
//通过fromObject转换json字符串 - JSONObject
JSONObject json = JSONObject.fromObject(jsonStr);
System.out.println(json);
{"derek":23,"dad":49,"mom":45}
直接输出,源字符串已经是满足JSON规范的,准换后还是JSON格式
Map<String,Object> map = new LinkedHashMap<>();
map.put("derek","23");
map.put("dad", "49");
map.put("mom", "45");
//通过fromObject转换Map对象 - JSONObject
JSONObject json2 = JSONObject.fromObject(map);
System.out.println(json2);
{"derek":"23","dad":"49","mom":"45"}
Map属于键值对,所以用JSONObject转换便可以(JSONArray转换就错了,下边有例子将JSONObject转List的错误示范)
//通过构造函数创建JSONObject对象 - JSONObject
JSONObject json1 = new JSONObject();
json1.put("1", "1");
System.out.println(json1);
{"1":"1"}
JSONObject的直接类似Map,直接put,内容已经是json格式的字符串了
List<Map<String, Object>> list = new LinkedList<>();
list.add(map);
System.out.println(JSONObject.fromObject(list));
net.sf.json.JSONException: 'object' is an array. Use JSONArray instead
JSONObject也就不能转换list数据。和JSON的结构说明一致,有序列表javascript解释为array
//通过fromObject转换List - JSONArray
System.out.println(JSONArray.fromObject(list));
[{"derek":"23","dad":"49","mom":"45"}]
JSONArray转换的序列都是以[]包裹的内容,这里Map是键值对,所以继续保存键值效果。
//通过构造函数创建JSONArray对象 - JSONArray
JSONArray json4 = new JSONArray();
json4.add(0,"derek");
json4.add(1,"dad");
json4.add(2,"mom");
System.out.println(json4);
["derek","dad","mom"]
JSONArray对象添加的内容都是单独的字符串,参考add函数
public void add(int index, Object value)
{
add(index, value, new JsonConfig());
}
index只是索引,所以其实他们都是数组,即使上边的转换Map的JSONArray,一个Map作为一个数组对象。
net.sf.json
参考文档:http://www.boyunjian.com/javadoc/net.sf.json-lib/json-lib/2.4/jdk13/设置JsonConfig建议参考JsonConfig的API,妹的setJsonPropertyFilter和setJavaPropertyFilter天壤之别啊。害苦人
如果对象结构中存在循环则应设置循环检测策略setCycleDetectionStrategy()对应的循环检测策略有三种:
LENIENT--LenientCycleDetectionStrategy宽容的循环检测(检测到重复引用返回一个新对象JSONObject||JSONArray)
NOPROP--LenientNoRefCycleDetectionStrategy宽容的没有参考的循环检测(检测到重复引用通过父类返回一个新对象JSONObject||JSONArray)
STRICT--StrictCycleDetectionStrategy强制的循环检测(检测到的重复引用抛异常)
JsonConfig.class
默认使用抛异常的方法检测重复引用
private static final CycleDetectionStrategy DEFAULT_CYCLE_DETECTION_STRATEGY = CycleDetectionStrategy.STRICT;
public void setCycleDetectionStrategy(CycleDetectionStrategy cycleDetectionStrategy)
{
this.cycleDetectionStrategy = (cycleDetectionStrategy == null ? DEFAULT_CYCLE_DETECTION_STRATEGY : cycleDetectionStrategy);
}
<pre name="code" class="html">CycleDetectionStrategy类中定义了两个抽象函数
处理JSONArray是遇到重复引用
public abstract JSONArray handleRepeatedReferenceAsArray(Object paramObject);
处理JSONObject是遇到重复引用
public abstract JSONObject handleRepeatedReferenceAsObject(Object paramObject);
3种侧率都有继承CycleDetectionStrategy。
所以都进行了复写
匹配默认值处理DefaultValueProcessorMatcher(JsonBeanProcessorMatcher,JsonValueProcessorMatcher,PropertyExclusionClassMatcher,PropertyNameProcessorMatcher)几个类的代码内容一样
和DefaultDefaultValueProcessor等一些处理类在一个包下边。用户处理解析的数据。
当且仅当 本set包含一个元素 e,并且满足(o==null ? e==null : o.equals(e))条件时,contains()方法才返回true. 因此 contains()方法 必定使用equals方法来检查是否相等.
public Object getMatch(Class target, Set set)
{
if ((target != null) && (set != null) && (set.contains(target))) {
return target;
}
return null;
}
set 中是可以包含 null值的(常见的集合类都可以包含null值). 所以如果添加了null,然后判断是否包含null,将会返回true,
HashSet<Dog> a = new HashSet<Dog>();
a.add(null);
if(a.contains(null)){
System.out.println("true");
}
新的bean实例策略NewBeanInstanceStrategy
在子类中一个重写的方法可能只抛出父类中声明过的异常或者异常的子类。这只适用于
方法重写而不适用于方法重载。所以如果如果一个方法有完全相同的名称和参数,它只能抛
出父类中声明过的异常或者异常的子类。
重写:子类的方法覆盖父类的方法,要求方法名和参数都相同
重载:在同一个类中的两个或两个以上的方法,拥有相同的方法名,但是参数却不相同,方法体也不相同,最常见的重载的例子就是类的构造函数
<span style="font-size:14px;">java类的方法重写时规定子类方法重写不能抛出超越父类方法定义的异常类的范围</span>
public abstract Object newInstance(Class paramClass, JSONObject paramJSONObject)
throws InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException, InvocationTargetException;
import java.lang.reflect.Constructor;
public Object newInstance(Class target, JSONObject source)
throws InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException, InvocationTargetException {
if (target != null) {
Constructor c = target.getDeclaredConstructor(EMPTY_PARAM_TYPES);
c.setAccessible(true);
try {
return c.newInstance(EMPTY_ARGS);
}
catch (InstantiationException e) {
String cause = "";
try {
cause = e.getCause() != null ? "\n" + e.getCause().getMessage() : "";
} catch (Throwable t) {}
throw new InstantiationException("Instantiation of \"" + target + "\" failed. " + "It's probably because class is an interface, " + "abstract class, array class, primitive type or void." + cause);
}
}
return null;
}
参考文档http://tool.oschina.net/apidocs/apidoc?api=jdk_7u4
http://blog.youkuaiyun.com/qq1130141391/article/details/12281113
java反射:
.java经过编译后成.class。在java中将.class看做是一个类对象。在java中使用java.lang.Class<T>这个类(所有的类型对象都在java.lang包中)去封装.class这一类对象。
反射就是把我们写的普通Java类中的各种成分映射成对应的Java类。Java类都有方法,构造方法和字段等成分,那么Java的反射中就会有Method,Constructor以及Field 和这些成分一一对应。java知道了.class中都包含了哪些内容,接下来就需要用到一个类装载器将.class加载到内存中。java虚拟机实例这些类装载器,这些类装载器为Java虚拟机工作。类装载器中包含了.class中的数据信息
java标识符转换JavaIdentifierTransformer
提出非java标示符开头的字符串
protected final String shaveOffNonJavaIdentifierStartChars(String str)
{
String str2 = str;
boolean ready = false;
while (!ready) {
if (!Character.isJavaIdentifierStart(str2.charAt(0)))//调用java.lang.Character的静态方法
{
str2 = str2.substring(1);
if (str2.length() == 0) {
throw new JSONException("Can't convert '" + str + "' to a valid Java identifier");
}
}
else
{
ready = true;
}
}
return str2;
}
<pre name="code" class="html">transformToJavaIdentifier抽象方法
CamelCaseJavaIdentifierTransformer驼峰命名java标识符(NoopJavaIdentifierTransformer,StrictJavaIdentifierTransformer,UnderscoreJavaIdentifierTransformer,WhiteSpaceJavaIdentifierTransformer)
都是字符转换规则
public String transformToJavaIdentifier(String str)
{
if (str == null) {
return null;
}
String str2 = shaveOffNonJavaIdentifierStartChars(str);
char[] chars = str2.toCharArray();
int pos = 0;
StringBuffer buf = new StringBuffer();
boolean toUpperCaseNextChar = false;
while (pos < chars.length)
{
if ((!Character.isJavaIdentifierPart(chars[pos])) || (Character.isWhitespace(chars[pos])))
{
toUpperCaseNextChar = true;
}
else if (toUpperCaseNextChar)
{
buf.append(Character.toUpperCase(chars[pos]));
toUpperCaseNextChar = false;
}
else
{
buf.append(chars[pos]);
}
pos++;
}
return buf.toString();
}
java.lang.Character源码,所有的Java标示符都是通过将char转换成int(ascii)获取对应的ascii
public static boolean isJavaIdentifierPart(int codePoint) {
// Use precomputed bitmasks to optimize the ASCII range.
//这里要注意普通ASCII的规范是8比特位的二进制,所以最大为128
//因为支持多国语言所以后来编码都是扩展到16位支持。
//算法很简单,想要几就将对应第几位写入1,组合成已转01的串(其实是2进制了,然后转换成了16进制进行运算)
//用位运算速度的确快
if (codePoint < 64) {
//64代表第一个字母A
return (0x3ff00100fffc1ffL & (1L << codePoint)) != 0;
} else if (codePoint < 128) {
return (0x87fffffe87fffffeL & (1L << (codePoint - 64))) != 0;
}
int type = getType(codePoint);
return (type >= UPPERCASE_LETTER && type <= OTHER_LETTER)
|| type == CURRENCY_SYMBOL || type == CONNECTOR_PUNCTUATION
|| (type >= DECIMAL_DIGIT_NUMBER && type <= LETTER_NUMBER)
|| type == COMBINING_SPACING_MARK || type == NON_SPACING_MARK
|| (codePoint >= 0 && codePoint <= 8) || (codePoint >= 0xe && codePoint <= 0x1b)
|| (codePoint >= 0x7f && codePoint <= 0x9f) || type == FORMAT;
}
JsonConfig配置json
private List ignoreFieldAnnotations = new ArrayList();
添加注释忽略不需要的字段
public void addIgnoreFieldAnnotation(Class annotationClass)
{
if ((annotationClass != null) && (!this.ignoreFieldAnnotations.contains(annotationClass.getName()))) {
this.ignoreFieldAnnotations.add(annotationClass.getName());
}
}
public void addIgnoreFieldAnnotation(String annotationClassName)
{
if ((annotationClassName != null) && (!this.ignoreFieldAnnotations.contains(annotationClassName))) {
this.ignoreFieldAnnotations.add(annotationClassName);
}
}
有添加就有相应的移除
public void removeIgnoreFieldAnnotation(String annotationClassName)
{
if (annotationClassName != null) {
this.ignoreFieldAnnotations.remove(annotationClassName);
}
}
public void removeIgnoreFieldAnnotation(Class annotationClass)
{
if (annotationClass != null) {
this.ignoreFieldAnnotations.remove(annotationClass.getName());
}
}
Processor查询用find,设置用register,unregister取消注册以DefaultValueProcessor为例
对类型操作的处理器
public void registerDefaultValueProcessor(Class target, DefaultValueProcessor defaultValueProcessor)
{
if ((target != null) && (defaultValueProcessor != null)) {
this.defaultValueMap.put(target, defaultValueProcessor);
}
}
public void unregisterDefaultValueProcessor(Class target)
{
if (target != null) {
this.defaultValueMap.remove(target);
}
}
public DefaultValueProcessor findDefaultValueProcessor(Class target)
{
if (!this.defaultValueMap.isEmpty())
{
Object key = this.defaultValueProcessorMatcher.getMatch(target, this.defaultValueMap.keySet());
DefaultValueProcessor processor = (DefaultValueProcessor)this.defaultValueMap.get(key);
if (processor != null) {
return processor;
}
}
return DEFAULT_VALUE_PROCESSOR;
}
<pre name="code" class="html">PropertyFilter过滤器,设置用set,获取用get
public void setJsonPropertyFilter(PropertyFilter jsonPropertyFilter)
{
this.jsonPropertyFilter = jsonPropertyFilter;
}<pre name="code" class="html">public void setJsonPropertyFilter(PropertyFilter jsonPropertyFilter)
{
this.jsonPropertyFilter = jsonPropertyFilter;
}
发现一神奇地带http://www.sjsjw.com/kf_jiagou/
附赠一篇demo
http://www.sjsjw.com/kf_jiagou/article/023498ABA009242.asp