Java反射复习
三种实例化对象:
1、Class<?> cls = Class.forName("java.util.Date") ; ***
System.out.println(cls.getName()); 2、类.class 3、对象.getClass
Class<?> cls = Class.forName("java.util.Date") ;
Object obj = cls.newInstance() ; // 实例化对象,等价于 new java.util.Date() 等价于 Date date = new Date()
class Main{
public static void main(String[] args) {
System.out.println(new java.util.Date()==new java.util.Date());
//false
}
}
获得包名:
Class<?> cls = CLS.class ; // 取得Class类对象
System.out.println(cls.getPackage().getName()); 获得父类接口:
Class<?> cls = CLS.class ; // 取得Class类对象
System.out.println(cls.getSuperclass().getName());
// 取得实现的父接口对象
Class<?>[] iClass = cls.getInterfaces() ;
for (Class<?> class1 : iClass) {
System.out.println(class1.getName());
} 获得构造方法:
Class<?> cls = Person.class ;
// 取得类中的全部构造
Constructor<?>[] constructors = cls.getConstructors() ;
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);
} 获取指定参数的构造:
public Constructor<T> getConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException 在定义简单java类的时候一定要保留有一个无参构造 Class类通过反射实例化类对象的时候,只能够调用类中的无参构造。如果现在类中没有无参构造则无法使用Class
类调用,只能够通过明确的构造调用实例化处理。
反射获得Date构造方法:
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat; class Main{
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException,
IllegalAccessException, InvocationTargetException, InstantiationException {
Class<?> cls = Class.forName("java.text.SimpleDateFormat");
Constructor<?>[] constructor = cls.getConstructors();
for (Constructor<?> constructor1 : constructor){
System.out.println(constructor1);
} // SimpleDateFormat simpleDateFormat =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// String str = simpleDateFormat.format(new Date());
// System.out.println(str); Constructor<?> cons = cls.getConstructor(String.class);
System.out.println((SimpleDateFormat)cons.newInstance("yyyy-MM-dd HH:mm:ss"));
}
}
反射获得指定参数构造方法
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
class Person {
private String name ;
private int age ;
public Person(String name,int age) {
this.name = name ;
this.age = age ;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
class Test {
public static void main(String[] args) throws InstantiationException,
IllegalAccessException, NoSuchMethodException, SecurityException,
IllegalArgumentException, InvocationTargetException {
Class<?> cls = Person.class;
// 取得指定参数类型的构造方法对象
Constructor<?> cons = cls.getConstructor(String.class, int.class);
System.out.println(cons.newInstance("yuisama", 29));
}
}
public Method[] getMethods() throws SecurityException public Method getMethod(String name, Class<?>... parameterTypes) public static void main(String[] args) throws Exception {
Class<?> cls = Person.class ;
Method[] methods = cls.getMethods() ;
for (Method method : methods) {
System.out.println(method);
}
}
import java.lang.reflect.Method;
class Person {
private String name ;
private int age ;
public Person() {}
public Person(String name,int age) {
this.name = name ;
this.age = age ;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
} public class Test {
public static void main(String[] args) throws Exception {
Class<?> cls = Class.forName("www.java.hhy.Person") ;
// 任何时候调用类中的普通方法都必须有实例化对象
Object obj = cls.newInstance() ;
// 取得setName这个方法的实例化对象,设置方法名称与参数类型
Method setMethod = cls.getMethod("setName", String.class) ;
// 随后需要通过Method类对象调用指定的方法,调用方法需要有实例化对象
// 同时传入参数
setMethod.invoke(obj, "yuisama") ; // 相当于Person对象.setName("yuisama") ;
Method getMethod = cls.getMethod("getName") ;
Object result = getMethod.invoke(obj) ; // 相当于Person对象.getName() ;
System.out.println(result) ;
}
}
此类操作的好处是:不再局限于某一具体类型的对象,而是可以通过Object类型进行所有类的方法调用
--------------------------------------------------------- 属性的获取
public class Test {
public static void main(String[] args) throws Exception {
Class<?> cls = Class.forName("www.bit.java.testthread.Student") ;
{ // 普通代码
// 第一组-取得父类中全部属性
Field[] fields = cls.getFields() ;
for (Field field : fields) {
System.out.println(field) ;
}
}
System.out.println("------------------------");
{
// 第二组-取得类中全部属性
Field[] fields = cls.getDeclaredFields() ;
for (Field field : fields) {
System.out.println(field);
}
}
}
}
package www.bit.java.testthread;
import java.lang.reflect.Field;
class Person {
private String name ;
}
public class Test {
public static void main(String[] args) throws Exception {
Class<?> cls = Class.forName("www.bit.java.testthread.Person") ;
// 实例化本类对象
Object obj = cls.newInstance() ;
// 操作name属性
Field nameField = cls.getDeclaredField("name") ;
nameField.set(obj, "yuisama") ; // 相当于对象.name = "yuisama"
System.out.println(nameField.get(obj)); // 取得属性
}
}
自定义类加载器
cls.getClassLoader() = AppClassLoader(应用程序类加载器)
cls.getClassLoader().getParent()) = ExtClassLoader(扩展类加载器);
最顶层: Bootstrap(启动类加载器): 启动类加载器无法被Java程序直接引用。
-------------------------------------------------------------------
双亲委派模型:
我们的应用程序都是由这三种加载器互相配合进行加载的,如果有必要,还可以加入自定义的类加载器。
双亲委派模型要求除了顶层的父类加
载器外,其余的类加载器都应有自己的父类加载器。
双亲委派模型的工作流程是:如果一个类加载器收到了类加载请求,它首先不会自己去尝试加载这个类,而是把这
个请求委托给父类加载器去完成,每一个层次的类加载器都是如此。因此,所有的加载请求都应当传送到顶层的
BootStrap加载器中,只有当父加载器反馈无法完成这个加载请求时(在自己搜索范围中没有找到此类),子加载器
才会尝试自己去加载。
类加载器的双亲委派模型从JDK1.2引入后被广泛应用于之后几乎所有的Java程序中,但它并不是强制性约束,甚至
可以破坏双亲委派模型来进行类加载,最典型的就是OSGI技术。
双亲委派模式对于保证Java程序的稳定运行很重要。有一个显而易见的好处就是Java类随着它的类加载器一起具备
了一种带有优先级的层次关系。例如java.lang.Object类,它存放在rt.jar中,无论哪一个类加载器要加载这个类,
最终都是委派给处于顶端的启动类加载器进行加载。因此,Object类在程序的各种类加载器环境中都是同一个类
比较两个类相等的前提:必须是由同一个类加载器加载的前提下才有意义。否则,即使两个类来源于同一个Class
文件,被同一个虚拟机加载,只要加载他们的类加载器不同,那么这两个类注定不想等。
动态代理模式
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface ISubject { // 核心操作接口
public void eat(String msg, int num) ; // 吃饭是核心业务
}
class RealSubject implements ISubject {
@Override
public void eat(String msg ,int num) {
System.out.println("我要吃 "+num + "分量的 "+msg) ;
}
}
/**
* 动态代理类
*/
class ProxySubject implements InvocationHandler {
// 绑定任意接口的对象,使用Object描述
private Object target ;
/**
* 实现真实对象的绑定处理,同时返回代理对象
* @param target
* @return 返回一个代理对象(这个对象是根据接口定义动态创建生成的代理对象)
*/
public Object bind(Object target) {
// 保存真实主题对象
this.target = target ;
return
Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfac
es(),this) ;
}
public void preHandle() {
System.out.println("[ProxySubject] 方法处理前") ;
}
public void afterHandle(){
System.out.println("[ProxySubject] 方法处理后") ;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
this.preHandle() ;
// 反射调用方法
Object ret = method.invoke(this.target,args) ;
this.afterHandle() ;
return ret;
}
}
public class TestDemo {
public static void main(String[] args) {
ISubject subject =(ISubject) new ProxySubject().bind(new RealSubject()) ;
subject.eat("宫保鸡丁",20) ;
}
}
Java反射复习的更多相关文章
- Java反射复习笔记
目录 反射 获取反射的三种方式: Class对象的功能 获取 成员变量/成员变量们 获取 成员方法/成员方法们 获取构造方法们 获取全类名 Field:成员变量 Method:成员方法 Constru ...
- Java基础复习笔记系列 十三 反射机制
主题:Java反射机制 学习资料参考网址: 1.http://www.icoolxue.com 1.Java反射机制. 各种框架中都使用到了Java的反射机制. 两个类:java.lang.Class ...
- JAVA基础部分复习(五、JAVA反射)
关于反射: 1.需要了解jvm类的加载机制(java高级部分会详细介绍) 2.反射的API其实只要多看看API和源码,很容易就懂了. 下面是代码,简单讲解反射的使用: import java.lang ...
- java 反射机制复习笔记。
1.java 反射的作用(好处): (1)能够使我们很方便的创建灵活的代码,这些代码可以在运行时装配(运行时获取一个类实例),就不用在组件之间进行源代码链接了,大大提高系统的灵活性和扩展性. (2)与 ...
- 【转】JAVA反射与注解
转载自:https://www.daidingkang.cc/2017/07/18/java-reflection-annotations/ 前言 现在在我们构建自己或公司的项目中,或多或少都会依赖几 ...
- java异常复习
如果有时学东西概念太多了,可以反着学,从结果到过程,从代码到概念,也许就不会那么枯燥了,比如学反射的时候. java异常复习 异常和错误的区别? 异常:程序或环境本身出现错误.(程序员可以捕获并处理) ...
- java 反射基本认识
java 反射基本认识 最近重新复习java反射的知识,有了新的理解. class类? 在面向对象中,万事万物皆对象.类也是个对象,是java.lang.class类的实例对象. public cla ...
- 《Java基础复习》—常识与入门
突然发现自己Java基础的底子不到位,复习! 所记知识会发布在CSDN与博客网站jirath.cn <Java基础复习>-常识与入门 一.Java语言的知识体系图 分为三部分 编程语言核心 ...
- 第28章 java反射机制
java反射机制 1.类加载机制 1.1.jvm和类 运行Java程序:java 带有main方法的类名 之后java会启动jvm,并加载字节码(字节码就是一个类在内存空间的状态) 当调用java命令 ...
随机推荐
- bat脚本弹出消息示例(msg命令详细解释)
弹出消息的bat,其实就是通过批处理调用msg命令,msg是系统自在的一个可以发送信息的命令. 示例: @echo off rem 测试MSG msg * "ok" rem 测试M ...
- Confluence 6.9.0 安装
平台环境:centos 7.6 数据库版本:mysql-5.7.26,提前安装好,安装步骤略. 软件版本:Confluence6.9.0 所需软件:提前下载到本地电脑 atlassian-conflu ...
- Rust中的迭代器
和闭包一样,练代码 struct Counter { count: u32, } impl Counter { fn new() -> Counter { Counter {count: } } ...
- Python类的使用总结
Python是一个面向对象的解释型语言,所以当然也有类的概念.在Python中,所有数据类型都可以视为对象,当然也可以自定义对象.自定义的对象数据类型就是面向对象中的类(Class)的概念.之前接触类 ...
- 201871010134-周英杰《面向对象程序设计(java)》第十三周学习总结
201871010134-周英杰<面向对象程序设计(java)>第十三周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ ...
- mac os下切换pip3国内源并安装requests库
在使用Python的时候,经常会用到pip来安装模块,但是默认的下载源实在是特别慢,经常install的时候还会因为速度的原因直接报错,因此我们可以选择将下载源更改为国内的,这样就可以提高我们的下载速 ...
- 10-tensorflow-tf.concat()
Concatenates tensors along one dimension. t1 = [[1, 2, 3], [4, 5, 6]] t2 = [[7, 8, 9], [10, 11, 12]] ...
- NOIP 2003 乒乓球
洛谷 P1042 乒乓球 https://www.luogu.org/problemnew/show/P1042 JDOJ 1363: [NOIP2003]乒乓球 T1 https://neooj.c ...
- Codeforces Round #545 (Div. 2) E 强连通块 + dag上求最大路径 + 将状态看成点建图
https://codeforces.com/contest/1138/problem/E 题意 有n个城市(1e5),有m条单向边(1e5),每一周有d天(50),对于每个城市假如在某一天为1表示这 ...
- [LeetCode] 272. Closest Binary Search Tree Value II 最近的二分搜索树的值之二
Given a non-empty binary search tree and a target value, find k values in the BST that are closest t ...