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命令 ...
随机推荐
- 章节十四、9-Actions类鼠标悬停、滚动条、拖拽页面上的元素
一.鼠标悬停 1.在web网站中,有一些页面元素只需要我们将鼠标指针放在上面就会出现被隐藏的下拉框或者其它元素,在自动化的过程中我们使用Actions类对鼠标进行悬停操作. 2.案例演示 packag ...
- Django Form 的主要内置字段介绍
修改 urls.py,添加 path('field.html', views.field), 在 templates 下创建 field.html, 内容如下: <!DOCTYPE html&g ...
- mysql update运行超时解决方案
问题描述: 今天update(修改)mysql数据库中一张表时,发现时间很长,而且会失败.报错:Error Code: 1205. Lock wait timeout exceeded; try re ...
- SpringBoot使用Hibernate,实现自动创建数据库表【博客数据库设计】
我们准备设计博客,那就要设计数据库. 我们可以使用Hibernate来自动生成数据库. 博客数据库的结构: 实体类: 博客 Blog 博客分类 Type 博客标签 Tag 博客评论 Comment 用 ...
- Linux驱动开发常用调试工具---之内存读写工具devmem和devkmem【转】
转自:https://blog.csdn.net/gatieme/article/details/50964903 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原 ...
- shell脚本特殊符号——单引号、双引号、反引号、反斜杠
1. 单引号 ( '' ) 被单引号用括住的内容,将被视为单一字串. 2. 双引号 ( " " ) 被双引号用括住的内容,将被视为单一字串.双引号只要求忽略大多数,具体说,括在双 ...
- 莫烦TensorFlow_10 过拟合
import tensorflow as tf from sklearn.datasets import load_digits from sklearn.cross_validation impor ...
- 【作用域】词法作用域(静态作用域,如:js)、动态作用域(如:.bash脚本)
作用域 作用域是指程序源代码中定义变量的区域. 作用域规定了如何查找变量,也就是确定当前执行代码对变量的访问权限. JavaScript 采用词法作用域(lexical scoping),也就是静态作 ...
- cmd 批处理创建 IIS 站点
windows 创建站点命令 appcmd C:\Windows\System32\inetsrv\appcmd.exe SITE 虚拟站点的管理 APP 管理应用程序 VDIR 管理虚拟目录 APP ...
- Xamarin.Forms移动开发系列4 :XAML基础
摘要 本文介绍Xamarin.Forms创建用户界面的语言:XAML基础部分. 前言 本文介绍Xamarin.Forms定义用户界面的语言:XAML. 本篇篇幅较长,主要讲述XAML语法,以及对其他基 ...