一.反射

  反射就是在剖析一个类,了解这个类的构造,创建这个类对应的对象。

Class 代表字节码的类,代表类的类
Field 代表属性的类
Method 代表方法的类
Constructor 代表构造方法的类
Annotation 代表注解的类
Package 代表包的类

二.Class类

2.1 获取Class对象:必须有意义

①通过类名.class的方式来获取对应类的字节码对象

 import java.util.List;

 public class ClassDemo {
@SuppressWarnings("rawtypes")
public static void main(String[] args) { // 每一个Class对象对应了一个实际的类,因此要求每一个Class都必须有意义
// 如果允许随意创建Class对象,就会导致Class对象没有实际对应的类
// Class clz0 = new Class(); // 通过类名.class的方式来获取一个字节码对象
// clz表示的就是String的字节码
Class<String> clz = String.class;
System.out.println(clz); // clz2表示的就是List的字节码
Class<List> clz2 = List.class;
System.out.println(clz2); // clz3表示的就是String[]的字节码
Class<String[]> clz3 = String[].class;
System.out.println(clz3); }
}

类名.class

②通过对象.getClass()方法来获取这个对象对应的实际类的字节码对象

 public class ClassDemo {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
Object str = "abc";
Class<String> clz = (Class<String>) str.getClass();
System.out.println(clz);
}
} //输出:class java.lang.String

对象.getClass()

③通过Class.forName(类的全路径名)的方法来获取指定类的字节码对象

 import java.util.List;

 public class ClassDemo {
@SuppressWarnings("unchecked")
public static void main(String[] args) throws ClassNotFoundException {
Class<String> clz = (Class<String>) Class.forName("java.lang.String");
System.out.println(clz); Class<List> clz2 = (Class<List>) Class.forName("java.util.List");
System.out.println(clz2);
}
} //输出:
//class java.lang.String
//interface java.util.List

Class.forName(类的全路径名)

2.2创建由此对象表示的类的新实例

2.2.1 newInstance

字节码对象.newInstance();

用处之举例:

Cat和Dog都实现了Animal接口,利用向上造型,将字符串利用Properties进行更改,可实现任意创建Cat对象或者Dog对象。

 public class TestClassDemo {
@SuppressWarnings("unchecked")
public static void main(String[] args) throws Exception { // 表示获取了Animal类对应的字节码
//"cn.hdu.reflection.Cat"可以用Properties进去获取
Class<Animal> clz = (Class<Animal>) Class.forName("cn.hdu.reflection.Cat"); // 要求类中必须有无参构造
Animal a = clz.newInstance(); //产生对象
System.out.println(a); } } interface Animal {
} class Dog implements Animal { @Override
public String toString() {
return "Dog";
} } class Cat implements Animal { @Override
public String toString() {
return "Cat";
} }

AnimalCatDog

2.2.2 通过构造方法创建新实例

//只能获取public构造方法
Constructor<?>[] getConstructors()
Constructor<T> getConstructor(类<?>... parameterTypes) //不区分是否是public的构造方法
Constructor<?>[] getDeclaredConstructors()
Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
//需要用 Constructor对象.setAccessible(true);进行设置

举例:

 import java.lang.reflect.Constructor;

 public class ClassGetConstructorDemo {
public static void main(String[] args) throws Exception { // clz代表String类的字节码
Class<String> clz = String.class; // String(String)
// 只能获取public修饰的构造方法
Constructor<String> constructorPublic = clz.getConstructor(String.class);
String str = constructorPublic.newInstance("abc");
System.out.println(str); // String(byte[], int, int)
Constructor<String> constructorParameters = clz.getConstructor(byte[].class, int.class, int.class);
String str2 = constructorParameters.newInstance(new byte[] { 97, 98, 99, 100 }, 1, 3);
System.out.println(str2); // 获取指定的构造方法,不区分是否是public的
Constructor<String> constructorPrivate = clz.getDeclaredConstructor(char[].class, boolean.class);
// 暴力破解/暴力拆除
constructorPrivate.setAccessible(true);
String str3 = constructorPrivate.newInstance(new char[] { 'a', 'b', 'c' }, true);
System.out.println(str3);
} }

getConstructor

在String源码中是默认的,非public

2.3 获取方法

//public
Method getMethod(String name, 类<?>... parameterTypes)
Method[] getMethods() //获取所有公有方法(包含了父类的方法也包含Object类)  //非public
Method getDeclaredMethod(String name, 类<?>... parameterTypes)
Method[] getDeclaredMethods() //获取所有的成员方法,包括私有的(不包括继承的)
//m.setAccessible(true); //使用所指定的方法:Method的对象.invoke(Object obj, Object... args);
 import java.lang.reflect.Constructor;
import java.lang.reflect.Method; public class ClassGetMethodDemo { public static void main(String[] args) throws Exception { Class<String> clz = String.class; // 表示String(String)
Constructor<String> c = clz.getConstructor(String.class);
String str = c.newInstance("abcdefg"); // 获取charAt(int)
// 只能获取public修饰的方法
Method m = clz.getMethod("charAt", int.class);
// 执行方法对象
// 相当于char ch = str.charAt(3);
char ch = (char) m.invoke(str, 3);
System.out.println(ch); // 获取指定的方法
Method m2 = clz.getDeclaredMethod("lastIndexOfSupplementary", int.class, int.class);
m2.setAccessible(true);
int i = (int) m2.invoke(str, 2, 3);
System.out.println(i);
} }

getMethod

2.4 获取属性

//public
Field getField(String name)
Field[] getFields() //非public
Field getDeclaredField(String name)
Field[] getDeclaredFields()
//f.setAccessible(true); //Field类
获取:Object get(Object obj)
设置:void set(Object obj, Object value)
void setChar(Object obj, char c)
void setDouble(Object obj, double d)
void setInt(Object obj, int i)
... ...
 import java.lang.reflect.Constructor;
import java.lang.reflect.Field; public class ClassGetFieldDemo {
public static void main(String[] args) throws Exception { Class<String> clz = String.class; // 表示String(String)
Constructor<String> c = clz.getConstructor(String.class);
String str = c.newInstance("abcdefg"); // 获取类中指定的属性
Field f = clz.getDeclaredField("hash");
f.setAccessible(true);
System.out.println(f.get(str));
// 设置属性的值
f.set(str, 125);
// 获取属性的值
System.out.println(f.get(str));
}
}

getField

2.5 获取注解

<A extends Annotation>A getAnnotation(类<A> annotationClass)
Annotation[] getAnnotations() <A extends Annotation>A getDeclaredAnnotation(类<A> annotationClass)
Annotation[] getDeclaredAnnotations()

2.6 Class类其它常用方法

 import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.List; public class ClassDemo { @SuppressWarnings("rawtypes")
public static void main(String[] args) { Class<String> clz = String.class; // 获取这个类实现的所有的接口
Class[] ins = clz.getInterfaces();
for (Class c : ins) {
System.out.println(c);
} // 获取父类
Class superc = clz.getSuperclass();
System.out.println(superc); // 获取类的全路径名
System.out.println(clz.getName());
// 获取类的简称
System.out.println(clz.getSimpleName()); // 获取所在的包
System.out.println(clz.getPackage()); List<String> list = new ArrayList<>();
Class lclz = list.getClass();
TypeVariable[] ts = lclz.getTypeParameters();
for (TypeVariable typeVariable : ts) {
System.out.println(typeVariable);
} // 判断是否是一个枚举
System.out.println(clz.isAnnotation());
// 判断是否是一个基本类型
System.out.println(clz.isPrimitive()); // 判断参数是否是指定类型的实例的
Object str = "abc";
System.out.println(clz.isInstance(str));
System.out.println(str instanceof String); // 判断两个类之间是否有继承关系
System.out.println(Object.class.isAssignableFrom(String.class)); } }

【java学习笔记】反射基础的更多相关文章

  1. Java学习笔记之---基础语法

    Java学习笔记之---基础语法 一. Java中的命名规范 (一)包名 由多个单词组成时,所有字母小写(例如:onetwo) (二)类名和接口 由多个单词组成时,所有单词首字母大写(例如:OneTw ...

  2. java学习笔记之基础篇

    java选择语句之switch   //switch可以用于等值判断 switch (e) //int ,或则可以自动转化成int 的类型,(byte char short)枚举jdk 7中可以防止字 ...

  3. Java学习笔记--反射

    什么是Java反射 概念 java反射是指java能够在运行时确定类的类型信息,包括其方法.字段.构造函数等,并能够通过反射调用类或者类对象的方法.在Java中,java.lang.Class类与ja ...

  4. C#学习笔记----反射基础

    反射基础 反射用于在程序运行过程中,获取类里面的信息或发现程序集并运行的一个过程.通过反射可以获得.dll和.exe后缀的程序集里面的信息.使用反射可以看到一个程序集内部的类,接口,字段,属性,方法, ...

  5. 0034 Java学习笔记-反射-初步2-操作对象

    通过反射创建对象 通过反射创建对象有两种方式,一种通过Class对象的newInstance()方法,一种是获取到Class对象的Constructor后,再调用newInstance()方法,前者要 ...

  6. 0033 Java学习笔记-反射-初步1

    先看看通过反射能干嘛 示例:修改对象的private实例变量 package testpack; import java.lang.reflect.Field; public class Test1 ...

  7. Java学习笔记--反射API

    反射API 1.反射API的介绍 通过反射API可以获取Java程序在运行时刻的内部结构.比如Java类中包含的构造方法.域和方法等元素,并可以与这些元素进行交换.     按照 一般地面向对象的设计 ...

  8. Java 学习笔记 反射与迭代器

    反射 使用反射获得类 Class cls = Class.forName("全类名") //包括包名 Class cls = xx.Class;//xx代表类名 使用反射获得构造方 ...

  9. JAVA 学习笔记 - 反射机制

    1.   JAVA反射机制的概念 2. 怎样实例化一个 Class对象 Class.forName(包名.类名); 对象.getClass(); 类.class; ================== ...

  10. Java学习笔记——反射

    反射就是把Java类中的各种成分映射成相应的java类. Class类-->java程序中的各个java类属于同一事物,描述这类事物的Java类名就是Class. Class.forName的作 ...

随机推荐

  1. Hadoop-2.6.5安装

    简介 Hadoop是一个由Apache基金会所开发的分布式系统基础架构. 用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群的威力进行高速运算和存储. Hadoop实现了一个分布式文 ...

  2. DELL服务器硬件信息采集SHELL脚本

    DELL服务器硬件信息采集SHELL脚本最近需要做资产列表,要采集DELL服务器的硬件信息,包括如下信息:1.操作系统信息(类型,版本,内核,平台,主机名)2.主板信息(厂商,机型,序列号)3.CPU ...

  3. C#常见问题总结(二)

    1.erp系统可以在具有固定ip的拥有多层服务器的局域网中使用吗?如何使用 解决方法: 把ini.配置文件字符串中的服务器名改成服务器的,把debug文件夹拷到其他机器上就行,服务器上的服务器名是默认 ...

  4. OS模块的常用内置方法

    chdir 修改当前工作目录到指定目录 Change the current working directory to the specified path. chmod 修改一个文件的访问权限 Ch ...

  5. Java高并发的常见应对方案

    Java高并发的常见应对方案 一.关于并发我们说的高并发是什么? 在互联网时代,高并发,通常是指,在某个时间点,有很多个访问同时到来. 高并发,通常关心的系统指标与业务指标? QPS:每秒钟查询量,广 ...

  6. MUI体验框架

    1.      mui简介 1.1  缘起 1.基于jq的jqmobile,性能低的无法忍受,且UI难看 2.bootstrap这种响应式设计,性能在低端机不足,而且UI风格一看就是网页,不是App的 ...

  7. Azure Automation (5) 调整Azure SQL Database DTU

    <Windows Azure Platform 系列文章目录> 之前有客户提了需求,在9点以后,把Azure SQL Database DTU提高 在凌晨,把Azure SQL Datab ...

  8. 走进JavaScript——重拾函数

    创建函数 通过构造器的方式来创建函数,最后一个参数为函数体其他为形参 new Function('a','b','alert(a)') /* function anonymous(a,b) { ale ...

  9. 自兴人工智能-------------Python入门基础(1)

    Python 是一门简单易学且功能强大的编程语言. 它拥有高效的高级数据结构, 并且能够用简单而又高效的方式进行面向对象编程. Python 优雅的语法和动态 类型,再结合它的解释性,使其在大多数平台 ...

  10. Python md5解密

    这篇文章原来在我盘里存了好久了~    16年9月的.   这 Python的长进没多少啊.现在都17.4了 哎~~ Python之POST提交解密MD5 用易语言写出来md5解密软件后感觉一点成就感 ...