静态嵌套类(Static Nested Class)和内部类(Inner Class)的不同
2015-12-22 10:53
357 查看
答:Static Nested Class是被声明为静态(static)的内部类,它可以不依赖于外部类实例被实例化。而通常的内部类需要在外部类实例化后才能实例化,其语法看起来挺诡异的,如下所示。
/**
* 扑克类(一副扑克)
* @author 骆昊
*
*/public class Poker {private static String[] suites = {"黑桃", "红桃", "草花", "方块"};
private static int[] faces = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
private Card[] cards;
/**
* 构造器
*
*/public Poker() {
cards = new Card[52];
for(int i = 0; i < suites.length; i++) {
for(int j = 0; j < faces.length; j++) {
cards[i * 13 + j] = new Card(suites[i], faces[j]);
}
}
}
/**
* 洗牌 (随机乱序)
*
*/public void shuffle() {
for(int i = 0, len = cards.length; i < len; i++) {
int index = (int) (Math.random() * len);
Card temp = cards[index];
cards[index] = cards[i];
cards[i] = temp;
}
}
/**
* 发牌
* @param index 发牌的位置
*
*/public Card deal(int index) {
return cards[index];
}
/**
* 卡片类(一张扑克)
* [内部类]
* @author 骆昊
*
*/public class Card {private String suite; // 花色private int face; // 点数public Card(String suite, int face) {
this.suite = suite;
this.face = face;
}
@Overridepublic String toString() {
String faceStr = "";
switch(face) {
case 1: faceStr = "A"; break;
case 11: faceStr = "J"; break;
case 12: faceStr = "Q"; break;
case 13: faceStr = "K"; break;
default: faceStr = String.valueOf(face);
}
return suite + faceStr;
}
}
}
测试代码:
class PokerTest {
public static void main(String[] args) {
Poker poker = new Poker();
poker.shuffle(); // 洗牌
Poker.Card c1 = poker.deal(0); // 发第一张牌// 对于非静态内部类Card// 只有通过其外部类Poker对象才能创建Card对象
Poker.Card c2 = poker.new Card("红心", 1); // 自己创建一张牌
System.out.println(c1); // 洗牌后的第一张
System.out.println(c2); // 打印: 红心A
}
}
面试题 - 下面的代码哪些地方会产生编译错误?
class Outer {
class Inner {}
public static void foo() { new Inner(); }
public void bar() { new Inner(); }
public static void main(String[] args) {
new Inner();
}
}
注意:Java中非静态内部类对象的创建要依赖其外部类对象,上面的面试题中foo和main方法都是静态方法,静态方法中没有this,也就是说没有所谓的外部类对象,因此无法创建内部类对象,如果要在静态方法中创建内部类对象,可以这样做:
new Outer().new Inner();
---------------------------静态内部类的用法------------------------------------------------------------------
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.processors.JsonValueProcessor;
public class JsonUtil {
public static final String obj2Json(Object obj, String formatStr) {
String jsonStr = "[]";
if (CommonUtil.isEmpty(obj)) {
LoggerHelper.warn("传入的Java对象为空,不能将其序列化为Json格式");
} else {
JsonConfig cfg = new JsonConfig();
cfg.registerJsonValueProcessor(java.sql.Timestamp.class,
new JsonValueProcessorImp(formatStr));
cfg.registerJsonValueProcessor(java.util.Date.class,
new JsonValueProcessorImp(formatStr));
cfg.registerJsonValueProcessor(java.sql.Date.class,
new JsonValueProcessorImp(formatStr));
if (obj instanceof ArrayList) {
JSONArray jsonArray = JSONArray.fromObject(obj, cfg);
jsonStr = jsonArray.toString();
} else {
JSONObject jsonObject = JSONObject.fromObject(obj, cfg);
jsonStr = jsonObject.toString();
}
}
return jsonStr;
}
static class JsonValueProcessorImp implements JsonValueProcessor
{
/**
* 默认的格式
*/
private String format = "yyyy-MM-dd HH:mm:ss";
public JsonValueProcessorImp() {
};
public JsonValueProcessorImp(String format) {
this.format = format;
}
/**
* 格式化数组
*/
public Object processArrayValue(Object value, JsonConfig jsonConfig) {
String[] obj = {};
if (value instanceof java.util.Date[]) {
SimpleDateFormat sf = new SimpleDateFormat(format);
java.util.Date[] dates = (java.util.Date[]) value;
obj = new String[dates.length];
for (int i = 0; i < dates.length; i++) {
obj[i] = sf.format(dates[i]);
}
}
if (value instanceof Timestamp[]) {
SimpleDateFormat sf = new SimpleDateFormat(format);
Timestamp[] dates = (Timestamp[]) value;
obj = new String[dates.length];
for (int i = 0; i < dates.length; i++) {
obj[i] = sf.format(dates[i]);
}
}
if (value instanceof java.sql.Date[]) {
SimpleDateFormat sf = new SimpleDateFormat(format);
java.sql.Date[] dates = (java.sql.Date[]) value;
obj = new String[dates.length];
for (int i = 0; i < dates.length; i++) {
obj[i] = sf.format(dates[i]);
}
}
return obj;
}
/**
* 格式化单一对象
*/
public Object processObjectValue(String key, Object value,
JsonConfig jsonConfig) {
if(CommonUtil.isEmpty(value))
return "";
if (value instanceof Timestamp) {
String str = new SimpleDateFormat(format).format((Timestamp) value);
return str;
} else if (value instanceof java.util.Date) {
String str = new SimpleDateFormat(format).format((java.util.Date) value);
return str;
} else if (value instanceof java.sql.Date) {
String str = new SimpleDateFormat(format).format((java.sql.Date) value);
return str;
}
return value.toString();
}
public String getFormat() {
return format;
}
public void setFormat(String format) {
this.format = format;
}
}
}
/**
* 扑克类(一副扑克)
* @author 骆昊
*
*/public class Poker {private static String[] suites = {"黑桃", "红桃", "草花", "方块"};
private static int[] faces = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
private Card[] cards;
/**
* 构造器
*
*/public Poker() {
cards = new Card[52];
for(int i = 0; i < suites.length; i++) {
for(int j = 0; j < faces.length; j++) {
cards[i * 13 + j] = new Card(suites[i], faces[j]);
}
}
}
/**
* 洗牌 (随机乱序)
*
*/public void shuffle() {
for(int i = 0, len = cards.length; i < len; i++) {
int index = (int) (Math.random() * len);
Card temp = cards[index];
cards[index] = cards[i];
cards[i] = temp;
}
}
/**
* 发牌
* @param index 发牌的位置
*
*/public Card deal(int index) {
return cards[index];
}
/**
* 卡片类(一张扑克)
* [内部类]
* @author 骆昊
*
*/public class Card {private String suite; // 花色private int face; // 点数public Card(String suite, int face) {
this.suite = suite;
this.face = face;
}
@Overridepublic String toString() {
String faceStr = "";
switch(face) {
case 1: faceStr = "A"; break;
case 11: faceStr = "J"; break;
case 12: faceStr = "Q"; break;
case 13: faceStr = "K"; break;
default: faceStr = String.valueOf(face);
}
return suite + faceStr;
}
}
}
测试代码:
class PokerTest {
public static void main(String[] args) {
Poker poker = new Poker();
poker.shuffle(); // 洗牌
Poker.Card c1 = poker.deal(0); // 发第一张牌// 对于非静态内部类Card// 只有通过其外部类Poker对象才能创建Card对象
Poker.Card c2 = poker.new Card("红心", 1); // 自己创建一张牌
System.out.println(c1); // 洗牌后的第一张
System.out.println(c2); // 打印: 红心A
}
}
面试题 - 下面的代码哪些地方会产生编译错误?
class Outer {
class Inner {}
public static void foo() { new Inner(); }
public void bar() { new Inner(); }
public static void main(String[] args) {
new Inner();
}
}
注意:Java中非静态内部类对象的创建要依赖其外部类对象,上面的面试题中foo和main方法都是静态方法,静态方法中没有this,也就是说没有所谓的外部类对象,因此无法创建内部类对象,如果要在静态方法中创建内部类对象,可以这样做:
new Outer().new Inner();
---------------------------静态内部类的用法------------------------------------------------------------------
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.processors.JsonValueProcessor;
public class JsonUtil {
public static final String obj2Json(Object obj, String formatStr) {
String jsonStr = "[]";
if (CommonUtil.isEmpty(obj)) {
LoggerHelper.warn("传入的Java对象为空,不能将其序列化为Json格式");
} else {
JsonConfig cfg = new JsonConfig();
cfg.registerJsonValueProcessor(java.sql.Timestamp.class,
new JsonValueProcessorImp(formatStr));
cfg.registerJsonValueProcessor(java.util.Date.class,
new JsonValueProcessorImp(formatStr));
cfg.registerJsonValueProcessor(java.sql.Date.class,
new JsonValueProcessorImp(formatStr));
if (obj instanceof ArrayList) {
JSONArray jsonArray = JSONArray.fromObject(obj, cfg);
jsonStr = jsonArray.toString();
} else {
JSONObject jsonObject = JSONObject.fromObject(obj, cfg);
jsonStr = jsonObject.toString();
}
}
return jsonStr;
}
static class JsonValueProcessorImp implements JsonValueProcessor
{
/**
* 默认的格式
*/
private String format = "yyyy-MM-dd HH:mm:ss";
public JsonValueProcessorImp() {
};
public JsonValueProcessorImp(String format) {
this.format = format;
}
/**
* 格式化数组
*/
public Object processArrayValue(Object value, JsonConfig jsonConfig) {
String[] obj = {};
if (value instanceof java.util.Date[]) {
SimpleDateFormat sf = new SimpleDateFormat(format);
java.util.Date[] dates = (java.util.Date[]) value;
obj = new String[dates.length];
for (int i = 0; i < dates.length; i++) {
obj[i] = sf.format(dates[i]);
}
}
if (value instanceof Timestamp[]) {
SimpleDateFormat sf = new SimpleDateFormat(format);
Timestamp[] dates = (Timestamp[]) value;
obj = new String[dates.length];
for (int i = 0; i < dates.length; i++) {
obj[i] = sf.format(dates[i]);
}
}
if (value instanceof java.sql.Date[]) {
SimpleDateFormat sf = new SimpleDateFormat(format);
java.sql.Date[] dates = (java.sql.Date[]) value;
obj = new String[dates.length];
for (int i = 0; i < dates.length; i++) {
obj[i] = sf.format(dates[i]);
}
}
return obj;
}
/**
* 格式化单一对象
*/
public Object processObjectValue(String key, Object value,
JsonConfig jsonConfig) {
if(CommonUtil.isEmpty(value))
return "";
if (value instanceof Timestamp) {
String str = new SimpleDateFormat(format).format((Timestamp) value);
return str;
} else if (value instanceof java.util.Date) {
String str = new SimpleDateFormat(format).format((java.util.Date) value);
return str;
} else if (value instanceof java.sql.Date) {
String str = new SimpleDateFormat(format).format((java.sql.Date) value);
return str;
}
return value.toString();
}
public String getFormat() {
return format;
}
public void setFormat(String format) {
this.format = format;
}
}
}
相关文章推荐
- Centos修炼----->Centos7办公环境打造(No4 一音频和视频文件如何播放)
- iOS 开发:绘制像素到屏幕
- Ios高级绘图之路径剪切和蒙版
- js中国标准时间转换成datetime格式
- xml中处理特殊字符和转义字符
- Maven笔记(一)
- UIControl 纠错
- 解决:Hibernate 向Mysql插入中文数据乱码,出现???
- iOS UISearchController的使用
- Android PopupWindow全屏
- 设计模式 --代理模式--动态代理
- QT打开ROS工作空间时遇到的问题和解决方法
- Android之LoaderManager的使用
- ArcGIS教程:线密度分析的工作原理
- Sqoop增量导入Hive
- 互斥锁pthread_mutex_t的使用
- 如何使用MathType文件选项
- Maya Mel GUI入门
- 【jQuery】检测对象是否为空
- scrapy流程图片