黑马程序员---JAVA反射机制
来源:互联网 发布:有声读书软件 编辑:程序博客网 时间:2024/05/22 16:08
——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
反射的基石—Class类
Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。
基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象,是9个预定义的Class对象。
Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。
Java程序中的各个Java类属于同一事物描述这类事物的Java类目就是Class。举个例子:
人 是一类事物—>Person
Java类 是一类事物—>Class
区别class与Class
class 是java的关键字, 在声明java类时使用;
Class 是java JDK提供的一个类,完整路径为 java.lang.Class;
区别是指两个或两个以上的事物间的不同,当两种相似的事物作比较时,它们的不同点便是区别。
那么 class和Class的相似性就只有一个,那都是单词”class”,就是一个为首字母大写,一个为小写.
class和Class的作用:
1. class只用于类声明;
2. Class则用于抽象类的相关信息. java是面向对象的, 一般是把一些事物抽象成一个类,比如将学生信息抽象成Student这个类;Student类会抽象学生的姓名/性别/生日等信息;
那么java中也就把java中的类也抽象成了一个类叫Class;Class中抽象了类的包名/类名/属性数组/方法数组等;
//一般类的定义
Person p1=new Person()
//Class类的定义
Class cls2=Person.class //字节码
得到字节码的三种方式:
类目.class Person.class
对象.getClass p1.getClass();
Class.forName(“类目”) Class.forName(“java.lang.String”)
预定义对象的判断
int.class==Integer.TYPE
数组类型的Class实例对象
Class.isArray()
总之只要是在源程序中出现的类型,都有各自的Class对象,如:int[],void等
下面看一个小例子:
package reflect;public class ReflectDemo { public static void main(String[] args) { String str1="abc"; try { Class cls1=str1.getClass(); Class cls2=String.class; Class cls3=Class.forName("java.lang.String"); System.out.println(cls1==cls2);//true System.out.println(cls3==cls2);//true System.out.println(cls1.isPrimitive());//false System.out.println(int.class.isPrimitive());//true System.out.println(int.class==Integer.class);//false System.out.println(int.class==Integer.TYPE);//true System.out.println(int[].class.isPrimitive());//false System.out.println(int[].class.isArray());//true } catch (ClassNotFoundException e) { e.printStackTrace(); } }}
反射概念
反射就是把Java类中的各种成分映射成相应的java类,例如,一个Java类中用一个Class类对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等信息也用一个个的Java类来表示,就像汽车是一个类,汽车中的发动机,变速箱等也是一个类。表示Java类的Class类显然就是提供一系列的方法,来获得其中的变量,方法,构造方法包等信息,这些信息就是用相应的类的实例对象来表示,它们是Field、Method、Package、Constructor等
Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
Constructor类
Constructor类代表某个类中的一个构造方法
得到某个类所有构造方法:
Constructor[] constructors = Class.forName(“java.lang.String”).getConstructors();
得到某一个人构造方法:
Constructor constructor = Class.forName(“java.lang.String”).getConstructors(StringBuffer.class);
这个例子得到的是String类的String(StringBuffer buffer)构造方法
//获得方法是要用到类型
创建实例对象:
Constructor constructor=String.class
.getConstructor(StringBuffer.class);
String str2=(String)constructor.newInstance(
newStringBuffer(“abc”));
//调用获得的方法时,要用到上面相同类型的实例对象
Class.newInstance()
例子:String obj=(String) Class.forName(“java.lang.String”).newInstance();
该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象,该方法内部用到了缓存机制来保存默认构造方法的实例对象
Field类
Field类代表某个类中的一个成员变量
问,得到的Field对象时对应到类上面的成员变量,还是对应的对象上的成员变量?类只有一个,而该类的实例对象可能有多个,如果是与对象关联,关联的是哪一个对象呢?所以字段fieldX代表的是x的定义,而不是具体的变量,示例代码:
class ReflectPoint { private int x; public int y; public ReflectPoint(int x, int y) { this.x = x; this.y = y; }}package reflect;import java.lang.reflect.Field;public class ReflectDemo { public static void main(String[] args) { try { ReflectPoint pt1=new ReflectPoint(3, 5); Field fieldY=pt1.getClass().getField("y"); //fieldY的值是多少?5 是错的,fieldY不是对象上的变量,而是类上要用它去取某个对象上对应的值 System.out.println(fieldY.get(pt1)); Field fieldX=pt1.getClass().getDeclaredField("x"); fieldX.setAccessible(true); System.out.println(fieldX.get(pt1)); } catch (Exception e) { e.printStackTrace(); } }}
下面有一个需求,将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的“b”改成“a”,这是一个经典的例子
public class ReflectPoint { public String str1="ball"; public String str2="basketball"; public String str3="itcast"; @Override public String toString(){ return str1+":"+str2+":"+str3; }}import java.lang.reflect.Field;public class ReflectDemo { public static void main(String[] args) { try { ReflectPoint pt1=new ReflectPoint(); changeStringValue(pt1); System.out.println(pt1); } catch (Exception e) { e.printStackTrace(); } } private static void changeStringValue(Object obj) throws IllegalArgumentException, IllegalAccessException { Field [] fields=obj.getClass().getFields(); for(Field field:fields){ if (field.getType()==String.class) {//字节码只有一份,所以用== String oldValue=(String) field.get(obj); String newValue=oldValue.replaceAll("b", "a"); field.set(obj, newValue); } } }}
Method类
Method类 代表某个类中的成员方法
得到类中的某一个方法:
Method charAt=Class.forName(“java.lang.String”).getMethod(“charAt”,int.class)
调用方法:
str.charAt(1);
charAt.invoke(str,1)
如果传递给Method对象的invoke()方法的第一个参数为null,这有什么样的意义呢?说明该Method对象对应的是一个静态方法
用反射方式执行某个类中的main方法
写一个程序,这个程序能够根据用户提供的类名,去执行该类中的main方法
import java.lang.reflect.Method;public class ReflectDemo { public static void main(String[] args) { try { TestArgument.main(new String[]{"111","222"});//普通方式 //反射方式 String startingClassName=args[0]; Method mainMethod=Class.forName(startingClassName).getMethod("main", String[].class); mainMethod.invoke(null, (Object)new String[]{"111","222","333"}); } catch (Exception e) { e.printStackTrace(); } }}class TestArgument{ public static void main(String[] args) { for(String arg:args){ System.out.println(arg); } }}
注:
mainMethod.invoke(null, (Object)new String[]{“111”,”222”,”333”}),编译器会做特殊处理,编译时不把参数当数组看待,
- 黑马程序员-Java反射机制
- 黑马程序员-java反射机制
- 黑马程序员-Java反射机制
- 黑马程序员-JAVA反射机制
- 黑马程序员-Java反射机制
- 黑马程序员-JAVA反射机制
- 黑马程序员 java反射机制
- 黑马程序员---Java反射机制
- 【黑马程序员】Java反射机制
- 黑马程序员-Java反射机制
- 黑马程序员--Java 反射机制
- 黑马程序员-Java反射机制
- 黑马程序员---JAVA反射机制
- 《黑马程序员》Java 反射机制
- 黑马程序员-Java反射机制
- 黑马程序员-------- 浅谈JAVA反射机制
- 黑马程序员-加强版-java反射机制
- 黑马程序员-java 高新技术 反射机制
- iOS 官网的开发手册
- 当电脑都出bug了(一)(长更)
- mac 环境反编译android apk
- 面试
- Java 调用 matlab 程序
- 黑马程序员---JAVA反射机制
- Python 的列表排序
- LXC
- 重磅消息:JavaFX官方文档翻译完毕
- effective c++ 确定对象被使用前已经被初始化
- Alpha动画的简单使用
- TreeList <上>
- 一纸泛荒,难描心间眉伤
- XMLParser解析自定义的xml文档