黑马程序员 反射
来源:互联网 发布:阿里云客服考试好考吗 编辑:程序博客网 时间:2024/06/17 02:24
------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
反射
1、反射的基石:class
字节码:是class的实例对象。
得到字节码方式
1)class.forName
2)类名.class 如Person.class
3)对象.getClass()
isPrimitive()是否是基本类型的字节码
int.class==Integer.TYPE
数组类型的class 实例对象
class.isArray()
总之,只要是在源程序中出现的类型,都有各自的class实例对象。
例如:int[],void
2、反射:就是把java类中的各种成分映射成相应的java类。
3、 Constructor 构造方法
//选择哪个构造方法
Constructor cr1=String.class.getConstructor(StringBuffer.class);//参数可
以多个,如int.class等
//用这个方法时,传一个对象进去
String str2=(String)cr1.newInstance(new StringBuffer("abc"));
//获得方法时要要到类型
有class得到Constructor,再new object
4、Field类:代表某个类中的成员变量
需求:从Demo2.java中获取x,y到Demo1.java
Demo2
private int x;
public int y;
//alt+shift+s
public ReflectPointDemo(int x, int y) {
super();
this.x = x;
this.y = y;
}
Demo1 ReflectPointDemo rpd=new ReflectPointDemo(3, 5);
Field fdy=rpd.getClass().getField("y");
//fdy的值是多少? 5,wrong
//fdy不是对象身上的变量,而是类上的,要用它去取某个对象上对应的值
System.out.println("y="+fdy.get(rpd));
//Field fdx=rpd.getClass().getField("x");//无法获取私有
Field fdx=rpd.getClass().getDeclaredField("x");//获取私有
fdx.setAccessible(true);//强行获取
System.out.println("x="+fdx.get(rpd));
---------
需求:对Demo2.java中s1,s2,s3数据修改,在Demo1.java实现
Demo2.java
public String s1="wang";
public String s2="wei";
public String s3="song";
@Override //请编译器查询
public String toString() {
return s1+":"+s2+":"+s3;
}
Demo1.java
changeStringValue(rpd);//rpd属于上述中的rpd
System.out.println(rpd);
}
public static void changeStringValue(Object obj)throws Exception
{
Field[] fs=obj.getClass().getFields();
for(Field f:fs)
{
//字节码用等号比==,因为这里是同一份字节码
if(f.getType()==String.class){
String oldValue=(String)f.get(obj);
String newValue=oldValue.replace("w", "t");
f.set(obj, newValue);
}
}
5、Method类代表某个类中的一个成员方法
通常方式:System.out.Println(str.charAt(1))
反射方式: System.out.Println(charAt.invoke(str,1))
若传递给Method对象的invoke()方法的第一个参数为null,
那么该Method对象对应的一个静态方法
Demo1.java //调用str2.charAt(1),str2="abc";
Method mdCharAt=String.class.getMethod("charAt", int.class);
System.out.println("str2.charAt(1)="+mdCharAt.invoke(str2, 1));
//jdk1.4的方式
System.out.println("str2.charAt(1)="+mdCharAt.invoke(str2,new Object[]
{2}));
6、 外部函数调用Demo2.java的main函数
用发射的目的:
当不知道执行哪个class时,用这个更适应
通常: Demo2.main(new string{}{"1","2","3"});
//ReflectPointDemo.main(new String[]{"1","2","3"});
String startClassName=args[0];
Method mainMethod=Class.forName(startClassName).getMethod("main",
String[].class);
//mainMethod.invoke(null, new String[]{"1","2","3"});//此时会出现数组下
标越界,会对 new String[]{"1","2","3"}进行拆分
mainMethod.invoke(null,new Object[]{ new String[]{"1","2","3"}});
7、数组的反射:
int[] a1=new int[]{1,2,3};
int[] a2=new int[4];
int[][] a3=new int[2][3];
String[] s4=new String[]{"a","1",","};
System.out.println(a1.getClass()==a2.getClass());//字节码相同
//System.out.println(a1.getClass()==a3.getClass());
System.out.println(a1.getClass().getSuperclass().getName());
System.out.println(s4.getClass().getSuperclass().getName());
//都是java.lang.Object
//所以能实现
Object obj1=a1;//...
//但是一维int数组无法赋值给Object数组
Object[] ob=a3;
Object[] obs=s4;
System.out.println(a1);//[I@1fb8ee3 哈希口?@1fb8ee3
//于是采用Arrays工具类
System.out.println(Arrays.asList(a1));//[[I@1fb8ee3]
System.out.println(Arrays.asList(s4));//[a, 1, ,]
//数组的反射
printObject(a1);
printObject(s4);
}
public static void printObject(Object obj) {
Class clzz=obj.getClass();
if(clzz.isArray())
{
int len=Array.getLength(obj);
for(int i=0;i<len;i++)
System.out.print(Array.get(obj, i));
System.out.println();
}
}
8、 ArrayList_HashSet的比较及Hashcode分析
hashcode方法与hashSet类
分区域、通过算哈希值找区域,再找目标。提高了效率
hashSet类:去重复的引用
hashcode方法:通过计算哈希值,去等值对象。
练习 public static void main(String[] args) {
// TODO Auto-generated method stub
//Collection cn=new ArrayList();//size=4
Collection cn=new HashSet(); //size=3
ReflectPointDemo rpd =new ReflectPointDemo(3,3);
ReflectPointDemo rpd2=new ReflectPointDemo(4,4);
ReflectPointDemo rpd3=new ReflectPointDemo(3,3);
cn.add(rpd);//将引用添加进去
cn.add(rpd2);
cn.add(rpd3);
cn.add(rpd);//与第一个引用相同
//hashcat若引用相同则无法加入
//若在ReflectPointDemo添加hashCode(),用于去同点 size=2
rpd.y=7;//将rpd存放在其他地方,不被发现 ,使cn.remove(rpd);操作失败,
size=2
cn.remove(rpd);//删除rpd
System.out.println(cn.size());//4
}
ReflectPointDemo 中
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
9、实现框架功能
解决的核心问题:适应性强,时用长(如虚类)
项目->file 取名config.properties
className=java.util.ArrayList //size=4
className=java.util.HashSet //size=2
Demo.java
public static void main(String[] args)throws Exception
{
// TODO Auto-generated method stub
InputStream ips=new FileInputStream("config.properties");
Properties pop=new Properties();
pop.load(ips);
ips.close();//释放资源。
String className=pop.getProperty("className");//前后className不必一样,
但..
Collection cn=(Collection)Class.forName(className).newInstance();
ReflectPointDemo rpd =new ReflectPointDemo(3,3);
ReflectPointDemo rpd2=new ReflectPointDemo(4,4);
ReflectPointDemo rpd3=new ReflectPointDemo(3,3);
cn.add(rpd);//将引用添加进去
cn.add(rpd2);
cn.add(rpd3);
cn.add(rpd);//与第一个引用相同
System.out.println(cn.size());
}
- 黑马程序员--java 反射
- 黑马程序员之反射
- 黑马程序员之反射
- 黑马程序员__java_反射
- 黑马程序员_反射
- 黑马程序员 反射
- 黑马程序员--Java反射
- 黑马程序员--反射
- 黑马程序员-java-反射
- 黑马程序员:反射技术
- 黑马程序员_java反射
- 黑马程序员---反射
- 黑马程序员-反射
- 黑马程序员---反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员:反射
- 黑马程序员_反射
- [Android]使用ActivityGroup来切换Activity和Layout
- 特殊单链表的一些操作
- lua动态链接库(luaopen_*函数的使用)
- 远程桌面授权服务器没有提供许可证问题解决方法
- Kinect开发学习笔记之(一)Kinect介绍和应用
- 黑马程序员 反射
- 日期对比
- 数据库备份与7天清除数据库原始备份文件。
- 汉诺塔II(hdu1207)经典递推
- Oracle 中 decode 函数用法
- 媒体猫创始人:如何才能做好行业的生态圈?
- Handler基本使用
- Java NIO 系列教程
- 简单的Java多线程的使用