反射机制
        1.观察 Class 类的使用
        2.利用反射改善工程设计模式
        3.反射操作类结构
        
    content (内容)
        1.认识反射
            既然是反,那么就有正。正常的思路中只有知道一个类之后才可以产生实例化对象
            
            范例:正常的操作

package cn.mysterious.study3;

import java.util.Date;

public class ReflexMechanism {

    public static void main(String[] args) {
// TODO Auto-generated method stub
java.util.Date data = new Date();
System.out.println(data);
} }

所谓的反指的就是通过对象找到来源,那么在程序中,对象要想找到它的来源就必须依靠 Object 类提供的一个方法完成:
                public final Class<?> getClass()
                
            范例:观察反

package cn.mysterious.study3;

import java.util.Date;

public class ReflexMechanism {

    public static void main(String[] args) {
// TODO Auto-generated method stub
java.util.Date data = new Date();
System.out.println(data.getClass());
} }

现在发现通过 getClass() 取得的 Class 类对象,就可以直接找到该对象的来源
            
        2.实例化 Class 类
            Class 类是反射操作的源头,也就是说所有的反射操作都应该通过Class 完成,但是最有意思的是这个类的对象可以通过三种实例化
                第一种:利用 Object 类中的 getClass() 方法 ,必须有明确的实例化对象后可以调用

package cn.mysterious.study3;

import java.util.Date;

public class ReflexMechanism {

    public static void main(String[] args) {
// TODO Auto-generated method stub
java.util.Date data = new Date();
Class<?> cls = data.getClass();
System.out.println("全名:" + cls.getName());
System.out.println("类名:" + cls.getSimpleName());
} }

第二种:利用“ 类.class ”取得 Class 类的实例化对象,等到学习到 Hibernate , MyBatis 的时候会使用到此模式

package cn.mysterious.study3;

import java.util.Date;

public class ReflexMechanism {

    public static void main(String[] args) {
// TODO Auto-generated method stub
Class<?> cls = Date.class;
System.out.println("全名:" + cls.getName());
System.out.println("类名:" + cls.getSimpleName());
} }

(这个不知道怎么说 一个是有 import 调用好包 一个是出错?)

package cn.mysterious.study3;

public class ReflexMechanism {

    public static void main(String[] args)throws Exception {
// TODO Auto-generated method stub
Class<?> cls = java.util.Date.class;
System.out.println("全名:" + cls.getName());
System.out.println("类名:" + cls.getSimpleName());
} }

第三种:利用 Class 类的 static 方法取得
                    实例化 Class 对象: public static Class<?> forName(String className)throws ClassNotFoundException

package cn.mysterious.study3;

public class ReflexMechanism {

    public static void main(String[] args)throws Exception {
// TODO Auto-generated method stub
Class<?> cls = Class.forName("java.util.Date"); // 字符串
System.out.println("全名:" + cls.getName());
System.out.println("类名:" + cls.getSimpleName());
} }

现在最为重要的模式就是使用 Class.forName() 方法,它的好处是可以直接写字符串

        3.通过反射实例化对象(核心)
            如果要产生实例化对象,本质上来讲必须有关键字 new才可以实现,但是这一切在有了反射之后变了
            在 Class 类中提供有如下一个方法:public T newInstance()throws InstantiationException,IllegalAccessException
            
            范例:正常实例化对象

package cn.mysterious.study3;

import java.util.Date;

public class ReflexMechanism {

    public static void main(String[] args) {
// TODO Auto-generated method stub
Date data = new Date();
System.out.println(data);
} }

范例:反射实例化对象

package cn.mysterious.study3;

import java.util.Date;

public class ReflexMechanism {

    public static void main(String[] args) throws Exception {
Class<?> cls = Class.forName("java.util.Date"); // 字符串
Date data = (Date) cls.newInstance();// 实例化对象:new Date()
System.out.println(data);
} }

下面再观察一个自定义的类i对象实例化
            
            范例:自定义实例化对象

package cn.mysterious.study3;

class Person{
public Person(){
System.out.println("*** 新的 Person类对象实例化 ***");
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "人";
}
} public class ReflexMechanism { public static void main(String[] args) throws Exception {
Class<?> cls = Class.forName("cn.mysterious.study3.Person"); // 字符串
Person p = (Person) cls.newInstance();// 实例化对象:new Date()
System.out.println(p);
} }

反射实例化对象最终也要调用无参构造方法进行实例化操作
            
        4.工厂设计模式的修正(理解)
            工厂设计模式的本质就在于要想取得接口的实例化对象不要直接使用关键字 new ,而应该通过工厂取得
            (总结:只要是自己写的接口要想取得实例化对象,99%要写工厂类)
            
            范例:传统工厂设计

package cn.mysterious.study3;

interface Fruit{
public void eat();
}
class Apple implements Fruit{
@Override
public void eat() {
// TODO Auto-generated method stub
System.out.println("吃");
}
}
class Factory{
public static Fruit getInstance(String classNaame) {
if ("apple".equalsIgnoreCase(classNaame)) {
return new Apple();
}
return null;
}
} public class ReflexMechanism { public static void main(String[] args) throws Exception {
Fruit f = Factory.getInstance("apple");
f.eat();
} }

但是现在对于工厂设计模式却出现了一个挑战,如果喜爱女子增加了子类,那么意味着工厂类需要修改
            那么假如这个接口可能源源不断的生产新的子类。所以这个时候的工厂类设计就存在有新的问题了
            那么现在的关键性问题就在于new上了,new是照成本次设计失败的最大元凶。所以这个时候就可以通过反射来实现此时的工厂类

package cn.mysterious.study3;

interface Fruit{
public void eat();
}
class Apple implements Fruit{
@Override
public void eat() {
// TODO Auto-generated method stub
System.out.println("吃苹果");
}
}
class Orange implements Fruit{
@Override
public void eat() {
// TODO Auto-generated method stub
System.out.println("吃橙子");
}
}
class Factory{
public static Fruit getInstance(String classNaame) {
try {
return (Fruit) Class.forName(classNaame).newInstance();
} catch (Exception e) {
// TODO: handle exception
return null;
}
}
} public class ReflexMechanism { public static void main(String[] args) throws Exception {
Fruit f = Factory.getInstance("cn.mysterious.study3.Orange");
f.eat();
} }

以上的代码只是分析出了关键字 new 实例化对象与构造方法实例化对象的区别,但是并不意味着不使用 关键字 new

        5.调用构造方法
             利用 Class 类中的 newInstance 方法其主要的目的是可以取得类的实例化对象,但是这种取得的操作本身是存在有问题的。因为它只能调用类中的去参构造。
             如果类中没有提供无参构造方法,那么就必须明确的调用指定的构造方法实现对象的实例化操作
             要想实现这样的操作,那么必须要找到类中的构造方法定义:
                public Constructor<T> getConstructor(Class<?>... parameterTypes)throws NoSuchMethodException, SecurityException
            
            找到了 java.lang.reflect.Constructor 类之中在此类中提供有一个实例化对象的方法:
                实例化对象:
                    public T newInstance(Object... initargs)
                        throws InstantiationException,
                            IllegalAccessException,
                            IllegalArgumentException,
                            InvocationTargetException
                            
            范例:调用指定构造实例化对象

package cn.mysterious.study3;

import java.lang.reflect.Constructor;

class Person {
private String name;
private int age;
public Person(String name,int age){
this.name = name;
this.age = age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "姓名:" + this.name + ",年龄:" + this.age + "\n";
}
} public class ReflexMechanism { public static void main(String[] args) throws Exception {
Class<?> cls = Class.forName("cn.mysterious.study3.Person");
Constructor<?> cons = cls.getConstructor(String.class,int.class);
Person per = (Person) cls.newInstance();// 实例化对象:new Date()
System.out.println(per);
} }

还是类中提供无参构造省事
            
        6.调用方法
            类中的普通方法是在取得本类的实例化对象之后才可以进行调用的操作。所以即便使用了反射进行方法的调用
            那么也必须使用 newInstance() 取得实例化对象,在 Class 类中定义有如下取得方法对象的操作
                取得方法:
                    public Method getMethod(String name,Class<?>... parameterTypes)
                                throws NoSuchMethodException,SecurityException
            getMethod() 方法返回的是 java.lang.reflect.Method 类对象,在这个类中有一个最为重要的方法:
                调用方法:

public Object invoke(Object obj,Object... args)
throws IllegalAccessException,IllegalArgumentException,InvocationTargetException package cn.mysterious.study3; import java.lang.reflect.Constructor;
import java.lang.reflect.Method; class Person {
private String name;
public Person(String name){
this.name = name;
}
public String getName() {
return name;
}
} public class ReflexMechanism { public static void main(String[] args) throws Exception {
String attribute = "name"; // 要求? value = "少爷"
Class<?> cls = Class.forName("cn.mysterious.study3.Person");
Object obj = cls.newInstance(); // 实例化对象
Method setMrthod = cls.getMethod("set" + initcap(attribute), String.class);
Method getMrthod = cls.getMethod("get" + initcap(attribute));
setMrthod.invoke(obj, "少爷"); // 等价于: 对象。setName("少爷")
System.out.println(getMrthod.invoke(obj));
}
public static String initcap(String str){
return str.substring(0,1).toLowerCase() + str.substring(1);
}
}

以后程序中如果给了属性名称,类的完整名称,而后可以进行自动的赋值操作,那么基本上就是反射机制在里面起作用

        7.调用成员
            在类中的成员需要考虑两种因素(Class 类定义的方法)
                父类继承而来的成员: public Field getField(String name)throws NoSuchFieldException,SecurityException
                本类定义的成员: public Field getDeclaredField(String name)throws NoSuchFieldException,SecurityException
            在java中使用 java.lang.reflect.Field 类描述成员,在这个类中有两个方法:
                取得成员内容: public Object get(Object obj)throws IllegalArgumentException,IllegalAccessException
                设置成员内容: public void set(Object obj,Object value)throws IllegalArgumentException,IllegalAccessException
            但是需要注意的是所有属性几乎都要使用 private 封装,所以要想解决封装的困扰
            可以利用 Field 父类的方法完成( java.lang.reflect.AccessibleObject ):
                取消封装: public void setAccessible(boolean flag)throws SecurityException
            
            范例:直接进行属性调用

package cn.mysterious.study3;

import java.lang.reflect.Field;

import javax.naming.NameNotFoundException;

class Person { // (想法:可不可以继承,继承 person)
private String name; } public class ReflexMechanism { public static void main(String[] args) throws Exception {
Class<?> cls = Class.forName("cn.mysterious.study3.Person");
Object obj = cls.newInstance(); // 实例化对象
Field nameField = cls.getDeclaredFields();
nameField.setAccessible(true); // private 消失了
nameField.set(obj,"少公子"); // 对象。name = “少公子”;
System.out.println(nameField.get(obj));
}
}

几乎类中的一切定义形式都可以通过反射完成
        
    总结
        在基础学习阶段对于反射有个认识就行了,暂时不需要编写代码
        Class Constructor Method Field 类的作用应该有个印象
        反射与工厂设计模式结合的产物

菜鸡的Java笔记 - java 反射机制的更多相关文章

  1. 浅说Java中的反射机制(二)

    写过一篇Java中的反射机制,不算是写,应该是抄了,因为那是别人写的,这一篇也是别人写的,摘抄如下: 引自于Java基础--反射机制的知识点梳理,作者醉眼识朦胧.(()为我手记) 什么是反射? 正常编 ...

  2. java中的反射机制在Android开发中的用处

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反 ...

  3. 黑马程序员——【Java高新技术】——反射机制

    ---------- android培训.java培训.期待与您交流! ---------- 一.概述 1.Java反射机制:是指“在运行状态中”,对于任意一个类,都能够知道这个类中的所有属性和方法: ...

  4. Java 中的反射机制

    JAVA反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为ja ...

  5. JAVA类型信息——反射机制

    JAVA类型信息——反射机制 一.反射机制概述 1.反射机制:就是java语言在运行时拥有的一项自我观察的能力,java通过这种能力彻底了解程序自身的情况,并为下一步的动作做准备. 2.反射机制的功能 ...

  6. 浅说Java中的反射机制(一)

    在学习传智播客李勇老师的JDBC系列时,会出现反射的概念,由于又是第一次见,不免感到陌生.所以再次在博客园找到一篇文章,先记录如下: 引用自java中的反射机制,作者bingoideas.(()为我手 ...

  7. java学习之反射机制

    java语言区别于C,C++等准静态语言的最大特点就是java的反射机制.静态语言的最直接定义就是不能在运行时改变程序结构或变量的类型.按照这样的定义,python,ruby是动态语言,C,C++,J ...

  8. java基础之反射机制

    一.概念 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为jav ...

  9. 深入理解Java中的反射机制

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制. ...

  10. 谈一谈java里面的反射机制

    首先来看看百度百科中是如何定义的: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方 ...

随机推荐

  1. PHP的SPL扩展库(一)数据结构

    SPL 库也叫做 PHP 标准库,主要就是用于解决典型问题的一组接口或类的集合.这些典型问题包括什么呢?比如我们今天要讲的数据结构,还有一些设计模式的实现,就像我们之前讲过的观察者模式相关的接口在 S ...

  2. Dapr + .NET Core实战(十一)单机Dapr集群

    如何单机部署Dapr集群 第十篇讲过了K8S集群下如何使用Dapr运行程序,但是很多人一直在问如何单机下进行Dapr的负载,这节课我们来聊聊如何单机进行Dapr的负载. 首先要说的是单机下,通过 da ...

  3. ldirectord

    试想,LVS作为前端负载均衡设备,当后端服务器宕机时,LVS还会把用户请求发送到该服务器上,这对用户体验来说是极其糟糕的,因为用户的请求无法得到处理.那么是否有一种机制,能保证后端服务器的是否正常?或 ...

  4. Java-多态(上)

    什么是多态 同一方法可以根据发送对象的不同而采取多种不同的行为方式 一个对象实际类型是确定的 但指向其引用类型却有很多 注意事项 多态是方法的多态 属性没有多态 父类和子类 有联系 类型转换异常 Cl ...

  5. Lamport时间戳论文笔记

    本文主要参考文献[1]完成. 声明:本人仅在博客园发表了本文章,笔名LightningStar,其他网站均为转载. 笔记 私以为,论文中作者的核心工作是为分布式系统建立了一种数学模型,并基于这种数学模 ...

  6. 使用Mybatis的一些基本配置及Mybatis与数据库交互测试验证

    1.简介 什么是MyBatis? MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.My ...

  7. jenkins容器内安装python3

    前言 很多小伙伴可能在考虑 jenkins 拉取了 github 上的代码后,发现还越少 python3 环境,那能怎么办呢? 咨询了一位运维朋友给我的答案是,将 python3 挂载到容器工作目录上 ...

  8. 树莓派4B学习札记

    防静电 树莓派比较容易被静电损坏,要做好以下预防措施 使用的时候不要用手去触摸PCB和针脚!特别是上电之后! 拿板卡的时候,要习惯性拿板卡的边缘 勤洗手,勤摸墙壁,释放身上的静电 系统安装 8GB以上 ...

  9. SpringCloud 2020.0.4 系列之Eureka

    1. 概述 老话说的好:遇见困难,首先要做的是积极的想解决办法,而不是先去泄气.抱怨或生气. 言归正传,微服务是当今非常流行的一种架构方式,其中 SpringCloud 是我们常用的一种微服务框架. ...

  10. 配置pyenv环境

    git clone https://github.com/pyenv/pyenv.git ~/.pyenv echo 'export PYENV_ROOT="$HOME/.pyenv&quo ...