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命令 ...
随机推荐
- Django ORM 一对多 和 多对多
一对多 在 models.py 上定义: class Province(models.Model): name = models.CharField(max_length=32) def __str_ ...
- PHP基础(谈一谈Session&Cookie)
cookie和sessiond的主要区别 (1).保存位置稍有区别 cookie数据存放在客户的浏览器上,服务器端不用保存.session数据放在服务器上,本地内存也有一份. (2).安全性不同 co ...
- 002-Zabbix 前端配置
Zabbix 前端配置 [基于此文章的环境]点我快速打开文章 [官方地址]点我快速打开文章 第 1 步 在浏览器中,打开 Zabbix URL:http:// <server_ip_or_nam ...
- spring-cloud-kubernetes服务发现之在k8s环境下开发spring cloud应用
通常情况下,我们的线上的服务在迁移到k8s环境下的时候,都是采用平滑迁移的方案.服务治理与注册中心等都是采用原先的组件.比如spring cloud应用,在k8s环境下还是用原来的一套注册中心(如eu ...
- K8s集群中设置harbor仓库认证
一,获取harbor的登陆用户名和密码(demo_user/demo_pwd) 二,使用kubectl命令生成secret(不同的namespace要分别生成secret,不共用) kubectl c ...
- E07【餐厅】What would you recommend?
核心句型 What would you recommend? 你有什么推荐吗? 场景对话: A:What do you want to eat? 你想吃点什么? B:I don't know. ...
- 06-人脸识别-MTCNN的感性认识(转载)
找到一个总结很好的blog. 具体训练的过程会在后续的随笔中给出. 转载自: https://blog.csdn.net/lff1208/article/details/77328357 以下是内容: ...
- CBV和FBV用户认证装饰器
FBV装饰器用户验证 CBV装饰器用户验证 装饰器位置 或 或
- [BZOJ3538]坑爹的GPS
题目描述 Description 有一天,\(FJ\) 买了一辆车,但是,他一手下载了两个\(GPS\) 系统.好了现在麻烦的事情来了,\(GPS\) 有一个功能大概大家也知道,如果\(FJ\) 没有 ...
- 配置好运行后Error creating context 'spring.root': Could not load type from string value
在Webconfig文件的当前项目下引用相关项目