张孝祥Java笔记(17-27)

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;
例:
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
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值