Java 核心类库之反射机制
1:什么是反射机制?
2:反射机制它可以做什么呢?
3:反射机制对应的API又是什么?
1):通过反射机制来获取一个对象的全限定名称(完整包名),和类名;
7):获取一个类中所有的构造器,获取单个不带参数的构造器,获取带参数的构造器
9):动态加载资源文件
1.什么是反射机制
反射机制是在运行状态中,对于任意一个类,都能够知道类所有的属性和方法,对于任意一个对象,
都能调用它的方法和属性,这种动态获取方法和属性,动态调用方法和属性的功能,称为Java的反射机制。
2.反射机制它可以做什么
反射机制主要提供以下功能:
1:在运行时,判断任意一个对象所属的类 。
2:在运行时,构造任意一个类的对象。
3:在运行时,判断任意一个类所具有的成员变量和方法。
4:在运行时,任意调用一个类中的方法。
5:生成动态代理。
5.反射机制对应的API又是什么
通过一个对象来获取一个对象的全限定名称(完整包名)
包名:Classinstance 类名:MethodD
private static void GetName() {
Class claz=MethodD.class;//获取对象的类
String classname=claz.getName();
System.out.println(classname);//打印出:Classinstance.MethodD
}
实例化Class对象
package net.xsoftlab.baike;
public class TestReflect {
public static void main(String[] args) throws Exception {
Class<?> class1 = null;
Class<?> class2 = null;
Class<?> class3 = null;
// 一般采用这种形式
class1 = Class.forName("net.xsoftlab.baike.TestReflect");
class2 = new TestReflect().getClass();
class3 = TestReflect.class;
System.out.println("类名称 " + class1.getName());
System.out.println("类名称 " + class2.getName());
System.out.println("类名称 " + class3.getName());
}
}
获取对象的父类与实现的接口
package Classinstance; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.Serializable; //获取父类和实现的接口
public class GetparentAndInterface implements Serializable,ActionListener { public static void main(String[] args) {
Class<?> claz=GetparentAndInterface.class;//获取对象
//获取父类
//返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class。
Class<?>parent=claz.getSuperclass();
System.out.println(parent);//打印父类:class java.lang.Object
//获取该类中所有的实现接口
// getInterfaces()确定此对象所表示的类或接口实现的接口。
Class<?>[] InterFace=claz.getInterfaces();
for (Class<?> class1 : InterFace) {
System.out.println(class1);
} } public void actionPerformed(ActionEvent e) { } }
使用反射来调用方法
package Classinstance; import java.lang.reflect.Method; //使用反射调用方法
class InvokeClass {
public void methodOne() {
System.out.println("调用不带参数的方法!");
} public void methodTwo(String name) {
System.out.println("调用带一个参数的方法!" + name);
} private String methodThree(String name, int age) {
System.out.println("调用私有带两个参数的方法!" + name + "," + age);
return name + "," + age;
}
} public class MethodInvokeDemo {
public static void main(String[] args) throws Exception {
//获取类对象
Class<InvokeClass> clazz = InvokeClass.class;
//获取方法
Method md = clazz.getMethod("methodOne");
Object dowork = md.invoke(clazz.newInstance());//invoke();
System.out.println(dowork); //调用带参数的方法
Method md1 = clazz.getMethod("methodTwo", String.class);
Object dowork1 = md1.invoke(clazz.newInstance(), "张三");//invoke();
System.out.println(dowork1); //调用私有带两个参数的方法
Method md2 = clazz.getDeclaredMethod("methodThree", String.class, int.class);
md2.setAccessible(true);//设置可访问的私有成员
Object dowork2 = md2.invoke(clazz.newInstance(), "张三", 18);//invoke();
System.out.println(dowork2); //使用反射调用静态方法
Method md3 = clazz.getDeclaredMethod("methodThree", String.class, int.class);
md3.setAccessible(true);//设置可访问的私有成员
Object dowork3 = md3.invoke(null, "张三", 18);//invoke();
System.out.println(dowork3);
}
}
使用反射来调用数组参数(情况1:数组元素类型数基本类型 情况2:数组元素类型是引用类型)
package Classinstance; import java.lang.reflect.Method;
import java.util.Arrays; class Method2 {
public static void dowork(int[] arr) {
System.out.println("dowork被调用了" + Arrays.toString(arr));
} public static void dowork2(String[] arr) {
System.out.println("dowork2被调用了" + Arrays.toString(arr));
}
} public class MethodInvokeDemo2 {
//使用反射调用数组参数(可变参数)
public static void main(String[] args) throws Exception {
Class<Method2> clazz = Method2.class;
//情况1:数组元素类型数基本类型
Method md = clazz.getMethod("dowork", int[].class);
//md.invoke(null, 1,2,3,4,5,6);error
//Object dw=md.invoke(null, new int[]{1,2,3,4,5,6});
Object dw = md.invoke(null, new Object[] { new int[] { 1, 2, 3, 4, 5, 6 } });
System.out.println(dw);
//情况2:数组元素类型是引用类型
Method md1 = clazz.getMethod("dowork2", String[].class);
//md.invoke(null, new String[]{"a","b","c"});error
Object dw1 = md1.invoke(null, new Object[] { new String[] { "a", "b", "c" } });
System.out.println(dw1);
}
}
使用反射机制,动态拷贝数组
package Classinstance; import java.lang.reflect.Array;
import java.util.Arrays; //使用反射机制,动态拷贝数组
public class ArrayDemo {
public static void main(String[] args) {
int[] src = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
int[] dest = new int[10];
System.out.println(Arrays.toString(src));
Arraycopy(src, 2, dest, 3, 5);
System.out.println(Arrays.toString(dest));
} public static void Arraycopy(Object src, int srcPos, Object dest, int destPos, int length) {
//源数组和目标数组必须是数组类型
if (!src.getClass().isArray() || !dest.getClass().isArray()) {
throw new ArrayStoreException("源数组和目标数组不是数组类型");
}
//源数组和目标数组不能为null
if (src == null || dest == null) {
throw new NullPointerException("源数组和目标数组不能为null");
}
//源数组和目标数组的数组类型必须一致
if (src.getClass().getComponentType() != dest.getClass().getComponentType()) {
throw new ArrayStoreException("源数组和目标数组元素类型不一致");
}
//源数组和目标数组不想索引越界
if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > Array.getLength(src)
|| destPos + length > Array.getLength(dest)) {
throw new IndexOutOfBoundsException("索引越界");
}
//获取需要拷贝的元素
for (int index = srcPos; index < srcPos + length; index++) {
//给目标数组数组元素
Object val = Array.get(src, index);
Array.set(dest, destPos, val);
destPos++;
}
}
}
获取类中的所有的方法或者单个方法
package Classinstance; import java.lang.reflect.Method; class MethodD {
public void method1() { } public void method2(String name) {
} private String method3(String name, int age) {
return name + "," + age;
}
} public class GetMethodDemo { private static GetMethodDemo class2; //使用反射获取类中的方法
public static void main(String[] args) throws Exception {
getAll();
getOne();
GetName();
} //通过一个对象来获取一个对象的全限定名称(完整包名)
private static void GetName() {
Class claz = MethodD.class;//获取对象的类
String classname = claz.getName();
System.out.println(classname);//打印出:Classinstance.MethodD
} //获取类中的指定的一个方法
private static void getOne() throws Exception {
Class<MethodD> clasz = MethodD.class;
//获取类不带参数的方法
Method md = clasz.getMethod("method1");
//获取类中指定带一个参数的方法
Method md1 = clasz.getMethod("method2", String.class);
//获取类私有指定带两个参数的方法
Method md2 = clasz.getDeclaredMethod("method3", String.class, int.class);
System.out.println(md2);
} private static void getAll() {//获取类中的所有方法
Class<MethodD> clasz = MethodD.class;
/*
* 返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,
* 包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
*/
Method[] md = clasz.getDeclaredMethods();
System.out.println(md.length);
for (Method method : md) {
System.out.println(method);
} } }
获取一个类中所有的构造器,获取单个不带参数的构造器,获取带参数的构造器
package Classinstance; import java.lang.reflect.Constructor; class User {
public User() { } public User(String name) { } private User(String name, int age) { }
} //获取构造器
public class GetConstructor {
public static void main(String[] args) throws Exception {
getAll();
} //获取所有构造器
private static void getAll() throws Exception {
//1):获取构造器所在类的对象
Class<User> claz = User.class; //2):获取对象中的所有构造器
Constructor<?>[] con = claz.getConstructors();//getConstructors()获取类中带public的构造器,返回一个Constructors数组
for (Constructor<?> constructor : con) {
System.out.println(constructor);
}
Constructor<?>[] con1 = claz.getDeclaredConstructors();//getDeclaredConstructors()获取类中带所有的构造器,跟访问权限无关,返回一个Constructors数组
for (Constructor<?> constructor : con1) {
System.out.println(constructor);
}
//获取public User()的构造器
Constructor<User> con2 = claz.getConstructor();
System.out.println(con2);
// 获取public User(String name)的构造器
//注意:必须用getDeclaredConstructor();有访问权限才可以
Constructor<User> con3 = claz.getDeclaredConstructor(String.class, int.class);
System.out.println(con3);
}
}
使用反射调用构造器---->创建对象
package Classinstance; //使用反射调用构造器-->创建对象
import java.lang.reflect.Constructor; class Peson {
public Peson() {
System.out.println("无参数构造器");
} public Peson(String name) {
System.out.println("有参数构造器" + name);
} private Peson(String name, int age) {
System.out.println("有参数构造器" + name + "," + age);
}
} public class CteateObject {
public static void main(String[] args) throws Exception {
Cteate();
} public static void Cteate() throws Exception {
//获取构造器对象
Class<Peson> clasz = Peson.class;
Constructor<?> con1 = clasz.getDeclaredConstructor();
Constructor<?> con2 = clasz.getDeclaredConstructor(String.class);
Constructor<?> con3 = clasz.getDeclaredConstructor(String.class, int.class);
//创建对象
con2.newInstance("张三");//newInstance();创建此 Class 对象所表示的类的一个新实例
//设置构造器可以访问
con3.setAccessible(true);
con3.newInstance("李四", 15);
}
}
动态加载资源文件
package Classinstance; import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties; //动态加载资源文件
public class LoadResourceDemo {
public static void main(String[] args) throws Exception {
text1();
text2();
} //最好用的方法
private static void text2() throws Exception {
Properties p = new Properties();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream inStream = loader.getResourceAsStream("db.properties");
p.load(inStream);
System.out.println(p);
} private static void text1() throws Exception {
//一般方式
Properties p = new Properties();
InputStream inStream = new FileInputStream("file/db.properties");//
p.load(inStream);
System.out.println(p);
} }
Java 核心类库之反射机制的更多相关文章
- Java进阶之reflection(反射机制)——反射概念与基础
反射机制是Java动态性之一,而说到动态性首先得了解动态语言.那么何为动态语言? 一.动态语言 动态语言,是指程序在运行时可以改变其结构:新的函数可以引进,已有的函数可以被删除等结构上的变化.比如常见 ...
- Java基础学习笔记二十三 Java核心语法之反射
类加载器 类的加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,链接,初始化三步来实现对这个类进行初始化. 加载就是指将class文件读入内存,并为之创建一个Class对象.任 ...
- Java SE之初探反射机制
[Keywords]:Java,Hibernate,虚拟机,框架,SQL [Abstract]: 反射的概念:所谓的反射就是java语言在运行时拥有一项自观的能力,反射使您的程序代码能够得到装载到 ...
- java的RTTI和反射机制
RTTI,即Run-Time Type Identification,运行时类型识别.RTTI能在运行时就能够自动识别每个编译时已知的类型. 很多时候需要进行向上转型,比如Base类派生出Derive ...
- java.lang.Class<T> -- 反射机制
1反射机制是什么 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为jav ...
- 在JAVA中,关于反射机制的讨论
一.什么是反射机制 简单的来说,反射机制指的是程序在运行时能够获取自身的信息.在java中,只要给定类的名字, 那么就可以通过反射机制来获得类的所有信息. 二.哪里用到反射机制 ...
- java工厂类与反射机制
java 简单工厂类 2012-04-22 15:44:07| 分类: java | 标签:java工厂类 简单工厂类 |举报|字号 订阅 简单工厂模式需要由以下角色组成: 接口 ...
- JAVA(五)反射机制/Annotation
成鹏致远 | lcw.cnblog.com |2014-02-04 反射机制 1.认识Class类 在正常情况下,必须知道一个类的完整路径之后才可以实例化对象,但是在 java中也允许通过一个对象来找 ...
- java的泛型与反射机制
什么是泛型? 泛型,即“参数化类型”.顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参) ...
随机推荐
- Maven打包同一个jar有不同的:版本+时间戳(解决思路)
在我们的开发过程中,目前流行的版本控制工具maven,在项目开发阶段,大家都是通过发布SNAPSHOT快照版进行相互模块之间的依赖开发, 这个时候就会有一个问题,要是一天构建多次的快照版,会发现在项目 ...
- php+JQuery+Ajax简单实现页面异步刷新 (转)
页面显示如下: JQueryAjax.html中的代码如下(用的较为简单的$.post) <html> <head> <meta charset="UTF-8& ...
- Jenkins的用户管理
用户管理入口 Jenkins首页有一个用户,但是只能从那查看用户列表和信息,管理用户的入口在Jenkins->系统管理->管理用户 新建用户 在管理用户左侧有一个新增用户,点击后按照表单填 ...
- 关于.NET中的Session
Asp.net 默认配置下,Session莫名丢失的原因及解决办法正常操作情况下Session会无故丢失.因为程序是在不停的被操作,排除Session超时的可能.另外,Session超时时间被设定成6 ...
- 数据科学:numpy.where() 的用法
原文出处:numpy.where() 用法讲解 原创作者:massquantity numpy.where() 有两种用法: 1. np.where(condition, x, y) 满足条件(con ...
- java多线程练习实例
总结: 循环的使用率蛮高,Thraed.sleep(),try-catch语句 package com.aa; public class West { public static void main( ...
- java冒泡排序算法例子
总结:运行显示数组下标越界说明,数组长度a.length.表示数组的长度,但索引值是要减一的.勿忘 package com.c2; //冒泡排序 //从小到大的顺序排列 public class MA ...
- 1032 Sharing
题意:寻找两个链表的首个公共结点,输出其地址. 思路: 方法1. 如果LinkList1比LinkList2长,则让LinkList1先偏移(len1-len2)个结点,然后,让两个链表的的工作指针 ...
- php获取当前月月初至月末的时间戳,上个月月初至月末的时间戳
当前月 <?php $thismonth = date('m'); $thisyear = date('Y'); $startDay = $thisyear . '-' . $thismonth ...
- AJAX的流程是什么?
客户端产生js的事件 创建XMLHttpRequest对象 对XMLHttpRequest进行配置 通过AJAX引擎发送异步请求 服务器端接受请求并且处理请求,返回html或者xml内容 XML调用一 ...