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

Java是一门面向对象语言,万物皆对象。对象是由类new出来的。例如我们有一个Dog类:

public class Dog{ }

创建一个Dog对象:Dog dog = new Dog();这个dog就是一个对象。

既然万物皆对象,那么Dog这个类是什么类的对象呢?答案就是Class类的对象。在Java中所有类都是Class类的对象。官方叫做类的ClassType:类类型。

类类型的获取有三种方式:

Class c1 = Dog.class;

Class c2 = dog.getClass();

Class c3 = Class.forName("Dog");

通过类的类类型,可以创建类的实例对象: Dog dog = Dog.class.newInstance();

Class的常用操作:

package com.shtel.test.reflection;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method; //Class 测试
public class ClassTest { //定义私有构造器
@SuppressWarnings("unused")
private ClassTest() { } //定义一个有参构造器
public ClassTest(String name) {
this.name=name;
System.out.println("执行有参构造器");
} //定义两个私有属性,一个公共属性
private String name = "rose";
private Number age;
public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Number getAge() {
return age;
} public void setAge(Number age) {
this.age = age;
}
public String hobby; //定义一个无参的info方法
public void info() {
System.out.println("执行无参的info方法");
} //定义一个有参的info方法
public void info(String str) {
System.out.println("执行有参的info方法;参数="+str);
} //定义一个私有方法
private void pri() {
System.out.println("执行私有方法");
} //定义测试内部类
class Inner{} public static void main(String[] args) throws Exception { //获取ClassTest的类类型
Class<ClassTest> clazz = ClassTest.class; //获取ClassTest的全部构造器
Constructor[] decConstructors = clazz.getDeclaredConstructors();
System.out.println("ClassTest全部构造器:");
for(Constructor ctr : decConstructors) {
System.out.println(ctr);
} //获取ClassTest的全部public构造器
Constructor[] constructors = clazz.getConstructors();
System.out.println("ClassTest全部public构造器:");
for(Constructor ctr : constructors) {
System.out.println(ctr);
} //获取ClassTest全部public方法
Method[] methods = clazz.getMethods();
System.out.println("ClassTest全部public方法:");
for(Method mth : methods) {
System.out.println(mth);
} //获取指定放方法
System.out.println("获取指定方法:"+clazz.getMethod("info", String.class)); //获取ClassTest全部内部类
Class<?>[] inners = clazz.getDeclaredClasses();
System.out.println("ClassTest全部内部类:");
for(Class<?> inner : inners) {
System.out.println(inner);
} //获取ClassTest全部public属性
Field[] fileds = clazz.getFields();
System.out.println("ClassTest全部public属性:");
for(Field f : fileds) {
System.out.println(f);
} //获取ClassTest全部public属性
Field[] decFileds = clazz.getDeclaredFields();
System.out.println("ClassTest全部属性:");
for(Field f : decFileds) {
System.out.println(f);
} //通过Class创建对象
ClassTest ct = clazz.newInstance();
//指定构造器创建实例对象
ClassTest ct1 = clazz.getConstructor(String.class).newInstance("lucy");
System.out.println(ct.name);
System.out.println(ct1.name); //通过Class调用方法
Method info = clazz.getMethod("info", String.class);
info.invoke(ct1, "hello");
//通过Class调用私有方法
Method pri = clazz.getDeclaredMethod("pri");
//取消访问权限检查
pri.setAccessible(true);
pri.invoke(ct); //动态创建数组(java.lang.reflect包下还提供一个Array类,用来动态的创建数组操作数组)
Object arr = Array.newInstance(String.class, 10);
Array.set(arr, 0, "零");
Array.set(arr, 1, "一");
System.out.println(Array.get(arr, 0) +"\n"+ Array.get(arr, 1));
}
}
类的静态加载和动态加载: 编译时刻加载类称为静态加载,运行时刻加载类称为动态加载,使用new方法新建实例即为静态加载类,在编译时候就要加载全部类。 例子: public class CreateDog(){
public static void main(String[] args) {
//参数传入金毛,就创建金毛,调用对应bark方法
if(args[0].equals("JinMao")) {
new JinMao().bark();
}
//参数传入哈士奇,就创建哈士奇,调用对应bark方法
if(args[0].equals("HaShiQi")) {
new HaShiQi().bark();
}
}
}
//金毛类
public class JinMao(){
public void brak(){
System.out.println("JinMao !");
}
}

当我们编译CreateDog类的时候会报错,找不到HaShiQi这个类,因为这个类还没有写。这就是静态加载,要在编译时刻加载所有用到的类。假如某个项目有100个功能,每个功能都有一个类。那就必须这个一百个类都正常存在,那么这个程序才能使用。但是我们往往使用的就是其中一个功能,由于其他类的缺少,这个功能也不能使用。这就是静态加载的弊端。

为了解决这个问题,我们可以使用动态加载,将上面的例子修改如下:

public interface Dog {
void bark();
}
public Class JinMao implements Dog(){
public void bark(){
System.out.println("JinMao !");
}
}
public class CreateDog(){
public static void main(String[] args) {
try{
Dog dog = (Dog)Class.forName(args[0]).newInstance();
dog.bark();
} catch(Exception e){
e.printStackTrace();
}
}
}

这是再来编译程序就不会出错。当我们传入参数是JinMao的时候,就会调用JinMao.bark()方法。当我门传入参数是HaShiQi的时候会报ClassNotFoundException(因为没写HaShiQi类)。倘若我只想听金毛的叫声,这个程序是可以的,不会因为没有哈士奇而不能听金毛的叫声。这就解决了静态加载的弊端。

通过类类型可以获取这个类的所有的方法和属性:

public static void getClassMethodMessage(Object obj){
Class<? extends Object> c = obj.getClass();
Method[] methods = c.getMethods();
for(int i=0;i<methods.length;i++){
//获取类里的方法名称
System.out.print(methods[i].getName()+"(");
//获取方法的参数数组
Class<?>[] paramType = methods[i].getParameterTypes();
for(Class<?> c1 : paramType){
System.out.print(c1.getName()+",");
}
System.out.print(")");
System.out.println();
}
}
public static void getClassFiledMessage(Object obj){
Class<? extends Object> c = obj.getClass();
//获取类属性
Field[] fileds = c.getFields();
for(Field f:fileds){
System.out.println(f.getName());
}
}

通过反射调用方法:

public class ReflectTest {
public static void main(String[] args) {
try {
Class<Dog> c = Dog.class;
Dog dog = (Dog)c.newInstance();
Method eat = c.getMethod("eat",String.class);
eat.invoke(dog,"大骨头");
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class Dog {
private String DogName;
public String getDogName() {
return DogName;
}
public void setDogName(String dogName) {
DogName = dogName;
}
public void brak(){
System.out.println("狗叫了");
}
public void eat(String food){
System.out.println("我正在吃"+food);
}
}

Java基础之反射总结的更多相关文章

  1. 黑马程序员:Java基础总结----反射

    黑马程序员:Java基础总结 反射   ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 反射 反射的基石:Class类 Class类代表Java类,它的各个实例对象又分别 ...

  2. Java基础之一反射

    反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码))   一.反射的概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够 ...

  3. Java基础之—反射

    反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码))   一.反射的概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够 ...

  4. JAVA基础知识|反射

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

  5. java基础之反射机制

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

  6. java基础(十一 )-----反射——Java高级开发必须懂的

    本文我们通过一个实际的例子来演示反射在编程中的应用,可能之前大家对反射的学习,仅仅是停留在概念层面,不知道反射究竟应用在哪,所以是一头雾水.相信通过这篇教程,会让你对反射有一个更深层次的认知. 概念 ...

  7. java基础之反射---重要

    java反射: 反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)):   1:获取Class字节码文件对象的三种方式: /** ...

  8. 【Java基础】反射和注解

    前言 在Java中,反射机制和注解机制一直是一个很重要的概念,那么他们其中的原理是怎么样呢,我们不仅仅需要会使用,更要知其然而之所以然. 目录 反射机制 反射如何使用 注解定义 注解机制原理 注解如何 ...

  9. java基础篇---反射机制

    一.JAVA是动态语言吗? 一般而言,说到动态言,都是指在程序运行时允许改变程序结构或者变量类型,从这个观点看,JAVA和C++一样,都不是动态语言. 但JAVA它却有着一个非常突出的动态相关机制:反 ...

  10. Java 基础总结--反射的基本操作

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

随机推荐

  1. Auto ML自动特征工程

    Auto ML自动特征工程 特征工程是在做机器学习训练的过程中必不可少的环节,特征工程就是找出对模型结果有益的特征交叉关系,通常特征工程需要耗费算法工程师大量的精力去尝试.针对这样的场景,PAI推出智 ...

  2. springboot 集成 elk 日志收集功能

    Lilishop 技术栈 官方公众号 & 开源不易,如有帮助请点Star 介绍 官网:https://pickmall.cn Lilishop 是一款Java开发,基于SpringBoot研发 ...

  3. ContOS8 配置MariaDB

    导语: 该篇文章主要记录ContOS8安装MariaDB后的一些配置内容,若想要详细了解安装过程请移步至上一篇博文! 正文: 首先对MariaDB进行相关的简单配置 使用mysql_secure_in ...

  4. java数据提交时问题

    form 表单中的action有参数时,当method为get时,servlet无法获取该参数 ajax提交数据,servlet无法进行请求转发和重定向. ${pageContext.request. ...

  5. 多图:一文带你入门掌握JVM所有知识点

    本JVM系列属于本人学习过程当中总结的一些知识点,目的是想让读者更快地掌握JVM相关的知识要点,难免会有所侧重,若想要更加系统更加详细的学习JVM知识,还是需要去阅读专业的书籍和文档. 本文主题内容: ...

  6. 手把手使用Python进行语音合成,文字转语音

    目录 0. 太长不看系列,直接使用 1. Python调用标贝科技语音合成接口,实现文字转语音 1.1 环境准备: 1.2 获取权限 1.2.1 登录 1.2.2 创建新应用 1.2.3 选择服务 1 ...

  7. Centos8.3、mysql8.0主从复制实战记录

    引言 最近又上线了一个项目,感觉自己这段时间收获不少就想把自己做这个项目用的技术总结梳理一下.这个项目是我自己发起,领导们不是特别重视所以得到资源有限,资源有限的情况我只能选择手动搭建数据库环境,资源 ...

  8. 【模板】Noi-Linux 下的一些配置

    Noi-Linux 下的一些配置(C++) vim 编程 来自远古的编程神器 针对网上其他博客的配置做了简化 配置 set t_Co=256 //开启256色模式 默认是16色 让你的vim更好看 s ...

  9. 记Aspose.Word的使用中出现的问题

    最近实现一个功能,具体需求就是把数据库中的内容转换成word文档,文档中需要包含标题.目录以及表格信息. 这里我使用的是Aspose.Word类,这是一个很强大的文档操作工具包,实现了所有操作文档的所 ...

  10. centos7安装JDK、CentOS

    1.安装JDK 1.1查看系统是否已有自带的JDK rpm -qa |grep java rpm -qa |grep jdk rpm -qa |grep gcj 1.2卸载已有安装 如果没有输出信息, ...