jms:java message service
自定义快捷键,如syso…
workspace的设置影响其下所有project
双击断点,右键debug as,选中变量,右键watch,单步
低版本Java不能运行高版本Javac编译的程序,提示bad version number in .class file
final定义类表不可被继承、定义方法表不可被重载、定义变量表值不可被改变
——————/17反射基础
Java类属于同一类事物,描述这类事物的类名为Class(c大写)
Class类的实例对象为各个类在内存中的字节码
类名.class,如System.class
对象.getClass(),如new Date().getClass()
Class.forName("类名"),如Class.forName("java.util.Date"); //最常用
可能字节码曾被加载过,已存在于虚拟机,则直接返回;也可能需临时用类加载器加载
boolean,byte,char,short,int,long,float,double,void也可如:
Class cls=int.class;
例:
——————/18、19反射
new String(new StringBuffer("abc"));
通过反射实现上述:
Constructor ctor=String.class.getConstructor(StringBuffer.class);
//据参数区分获得哪个构造函数
String str=(String)ctor.newInstance(new StringBuffer("abc"));
//据ctor所在Class生成一新对象,返回为object,故强制类型转换
System.out.println(str.charAt(1));
注意:StringBuffer.class与new StringBuffer("abc")必须对应
String str=(String)String.class.newInstance();
本质与上同,据无参构造函数…,不常用
——————/20Field类
——————/21成员变量反射实例
将任一对象String变量所对应字符串内容中"b"改成"a"
aall aasketaall
——————/22 成员方法的反射
String str="lyl";
Method mod=str.getClass().getMethod("charAt",int.class); //据参数区分哪个方法,因有重载
System.out.println(mod.invoke(str,1)); //int.class与1要对应
结果:y
System.out.println(mod.invoke(NULL,1)); //说明为静态方法
jdk1.4和jdk1.5的invoke方法区别:
Jdk1.5:public Object invoke(Object obj,Object... args)
Jdk1.4:public Object invoke(Object obj,Object[] args) //1.4不存在可变参数
按1.4语法,如charAt.invoke(“str”, new Object[]{1}) //自动装箱,类似new int[]{1,2};
——————/23用反射方式执行某类main方法
选中Point按下F2出现完整类名com.baidu.www.Point
String startingClassName=args[0]; //"com.baidu.www.Point";
Method mainMethod=Class.forName(startingClassName).getMethod("main",String[].class);
mainMethod.invoke(null,new Object[]{new String[]{"1","2","3"}});
每个数组的父类都是object
最后一行如此mainMethod.invoke(null,new String[]{"1","2","3"});
符合道理,但报ArrayIndexOutOfBoundsException,因:
jdk1.5语法,整个数组是一参数,jdk1.4语法,数组中每个元素是一参数,当把一字符串数组作为参数传递给invoke方法时,javac为兼容jdk1.4,会把数组打散成若干单独参数,故在给main传参时,出现参数类型不匹配问题
——————/24
Point pt=new Point();
System.out.println(pt.getClass().getName());
System.out.println(pt.getClass().getSuperclass().getName());
结果:
com.baidu.www.Point
java.lang.Object
——————/
具相同维数和元素类型的数组属同一类型,即其Class实例对象相同:
——————/25数组反射
——————/
java.lang.String
java.lang.Integer
——————/26
——————/27框架开发举例
new——file——config.file内容:
className=java.util.ArrayList
Properties对象等效HashMap,即内存中为key——value,但在HashMap基础上功能扩展,即可将内存键值对写入硬盘或初始化时从硬盘文件加载键值对
自定义快捷键,如syso…
workspace的设置影响其下所有project
双击断点,右键debug as,选中变量,右键watch,单步
低版本Java不能运行高版本Javac编译的程序,提示bad version number in .class file
final定义类表不可被继承、定义方法表不可被重载、定义变量表值不可被改变
——————/17反射基础
Java类属于同一类事物,描述这类事物的类名为Class(c大写)
Class类的实例对象为各个类在内存中的字节码
类名.class,如System.class
对象.getClass(),如new Date().getClass()
Class.forName("类名"),如Class.forName("java.util.Date"); //最常用
可能字节码曾被加载过,已存在于虚拟机,则直接返回;也可能需临时用类加载器加载
boolean,byte,char,short,int,long,float,double,void也可如:
Class cls=int.class;
例:
Class cls1=Class.forName("java.lang.String");
Class cls2=String.class;
System.out.println(cls1==cls2); //true
System.out.println(cls1.isPrimitive()); //false非基本类型
System.out.println(int.class.isPrimitive()); //true
System.out.println(int[].class.isPrimitive()); //false
System.out.println(int[].class.isArray()); //true
——————/18、19反射
new String(new StringBuffer("abc"));
通过反射实现上述:
Constructor ctor=String.class.getConstructor(StringBuffer.class);
//据参数区分获得哪个构造函数
String str=(String)ctor.newInstance(new StringBuffer("abc"));
//据ctor所在Class生成一新对象,返回为object,故强制类型转换
System.out.println(str.charAt(1));
注意:StringBuffer.class与new StringBuffer("abc")必须对应
String str=(String)String.class.newInstance();
本质与上同,据无参构造函数…,不常用
——————/20Field类
public class Point { //Point.java
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int x;
private int y;
}
法一:
Point p=new Point(1,2);
Field x=p.getClass().getField("x"); //x为字节码一部分
System.out.println(x.get(p)); //x在p对象上的值
法二:
Point p=new Point(1,2);
Field y=p.getClass().getDeclaredField("y");
y.setAccessible(true);
System.out.println(y.get(p)); //必须如此,否则访问不到,因private属性
——————/21成员变量反射实例
将任一对象String变量所对应字符串内容中"b"改成"a"
public class Point {
public String str1="ball"; //需为public,否则getFields失败
public String str2="basketball";
}
Point pt=new Point();
Field[] fields=pt.getClass().getFields();
for(Field fld:fields){
if(fld.getType()==String.class){ //字节码一份
String strOld=(String)fld.get(pt);
String strNew=strOld.replace('b','a');
fld.set(pt,strNew);
}
}
System.out.println(pt.str1+" "+pt.str2);
结果:
aall aasketaall
——————/22 成员方法的反射
String str="lyl";
Method mod=str.getClass().getMethod("charAt",int.class); //据参数区分哪个方法,因有重载
System.out.println(mod.invoke(str,1)); //int.class与1要对应
结果:y
System.out.println(mod.invoke(NULL,1)); //说明为静态方法
jdk1.4和jdk1.5的invoke方法区别:
Jdk1.5:public Object invoke(Object obj,Object... args)
Jdk1.4:public Object invoke(Object obj,Object[] args) //1.4不存在可变参数
按1.4语法,如charAt.invoke(“str”, new Object[]{1}) //自动装箱,类似new int[]{1,2};
——————/23用反射方式执行某类main方法
选中Point按下F2出现完整类名com.baidu.www.Point
public class Point { //Point.java
public static void main(String[] args){
for(String arg:args){
System.out.println(arg);
}
}
}
class Test { //Test.java
public static void main(String args[]){
Point.main(new String[]{"1","2","3"});
}
} //1 2 3
利用反射调用原因(类名由参数获得)及方法:
String startingClassName=args[0]; //"com.baidu.www.Point";
Method mainMethod=Class.forName(startingClassName).getMethod("main",String[].class);
mainMethod.invoke(null,new Object[]{new String[]{"1","2","3"}});
每个数组的父类都是object
最后一行如此mainMethod.invoke(null,new String[]{"1","2","3"});
符合道理,但报ArrayIndexOutOfBoundsException,因:
jdk1.5语法,整个数组是一参数,jdk1.4语法,数组中每个元素是一参数,当把一字符串数组作为参数传递给invoke方法时,javac为兼容jdk1.4,会把数组打散成若干单独参数,故在给main传参时,出现参数类型不匹配问题
——————/24
Point pt=new Point();
System.out.println(pt.getClass().getName());
System.out.println(pt.getClass().getSuperclass().getName());
结果:
com.baidu.www.Point
java.lang.Object
——————/
具相同维数和元素类型的数组属同一类型,即其Class实例对象相同:
int[] a1=new int[3];
int[] a2=new int[4];
int[][] a3=new int[2][2];
String[] a4=new String[3];
System.out.println(a1.getClass() == a2.getClass()); //true
System.out.println(a1.getClass().getName()); //[I
System.out.println(a1.getClass().getSuperclass().getName()); //java.lang.Object
System.out.println(a3.getClass().getName()); //[[I
System.out.println(a3.getClass().getSuperclass().getName()); //java.lang.Object
Object obj1=a1; //正确,因其父类是Object
Object obj2=a4; //正确,因其父类是Object
//Object[] obj3=a1; //错误,因int父类非Object
Object[] obj4=a3; //正确,因int[][]可看成一维数组的数组,一维数组父类是Object
Object[] obj5=a4; //正确,因String[]为String的数组,String父类是Object
剩余内容看视频
——————/25数组反射
int[] a1=new int[]{1,2,3};
String str = "lyl";
printObject(a1);
printObject(str);
static void printObject(Object object) {
Class cls=object.getClass();
if(cls.isArray()){
int len=Array.getLength(object);
for(int i=0;i<len;i++){
System.out.println(Array.get(object, i));
}
}else{
System.out.println(object);
}
}
结果:1 2 3 lyl
——————/
Object[] obj=new Object[]{"lyl",1};
System.out.println(obj[0].getClass().getName());
System.out.println(obj[1].getClass().getName());
结果:
java.lang.String
java.lang.Integer
——————/26
//Collection cols=new ArrayList(); //4
Collection cols=new HashSet(); //3,如希望p1与p3等,则需自己实现equal方法
Point p1=new Point(1, 1);
Point p2=new Point(2, 2);
Point p3=new Point(1, 1);
cols.add(p1);
cols.add(p2);
cols.add(p3);
cols.add(p1);
System.out.println(cols.size());
hashCode作用见视频,经典
——————/27框架开发举例
new——file——config.file内容:
className=java.util.ArrayList
Properties对象等效HashMap,即内存中为key——value,但在HashMap基础上功能扩展,即可将内存键值对写入硬盘或初始化时从硬盘文件加载键值对
class Test {
public static void main(String args[]) throws Exception{
InputStream ips=new FileInputStream("config.file");
Properties props=new Properties();
props.load(ips);
ips.close(); //关闭文件
String className=props.getProperty("className");
Collection cols=(Collection)Class.forName(className).newInstance();
Point p1=new Point(1, 1);
cols.add(p1);
System.out.println(cols.size()); //1
}
}