Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键
Class对象是JVM生成用来保存对象的类的信息的。Java程序执行之前需要经过编译、加载、链接和初始化这几个阶段,编译阶段会将源码文件编译为.class
字节码文件,编译器同时会在.class
文件中生成Class对象,加载阶段通过JVM内部的类加载机制,将Class对象加载到内存中。在创建对象实例之前,JVM会先检查Class对象是否在内存中存在,如果不存在,则加载Class对象,然后再创建对象实例,如果存在,则直接根据Class对象创建对象实例。JVM中只有一个Class对象,但可以根据Class对象生成多个对象实例。
获取Class对象的三种方式
1.Class.forName方式 传全限定类名
public class Cat {
private int age;
private String name;
public static void main(String[] args) throws ClassNotFoundException {
Class<?> c1 = Class.forName("org.yrdm.ch1.Cat");
System.out.println(c1);
}
}
结果:
class org.yrdm.ch1.Cat
public class Cat {
private int age;
private String name;
public static void main(String[] args) {
Cat cat=new Cat();
Class c1 = cat.getClass();
System.out.println(c1);
}
}
结果:
class org.yrdm.ch1.Cat
3.通过类名 .class
public class Cat {
private int age;
private String name;
public static void main(String[] args) {
Class c1 = Cat.class;
System.out.println(c1);
}
}
结果:
class org.yrdm.ch1.Cat
Class类源码分析
//泛型类
public final class Class<T> implements java.io.Serializable,GenericDeclaration,Type,AnnotatedElement {
//重要方法
//获取Class对象 static修饰
@CallerSensitive
public static Class<?> forName(String className)
throws ClassNotFoundException {
Class<?> caller = Reflection.getCallerClass();
return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}
//创建实例,直接调用无参构造进行构造 jdk9后被弃用,使用class.getDeclaredConstructor().newInstance()代替
@CallerSensitive
@Deprecated(since="9")
public T newInstance()
throws InstantiationException, IllegalAccessException
{...}
//每个结构都有这四件套 getXXX() getXXXs() getDealaredXXX() getDeclaredXXXs()
//1.属性
//根据参数获取属性 public 属性
@CallerSensitive
public Field getField(String name){...}
//获取所有public属性,返回属性数组
@CallerSensitive
public Field[] getFields() throws SecurityException {
...
}
//Returns an array of Field objects reflecting all the fields declared by the class or interface represented by this Class object. 获取所有属性,public protected default private
@CallerSensitive
public Field[] getDeclaredFields() throws SecurityException {
...
}
//Returns a Field object that reflects the specified declared field of the class or interface represented by this Class object.
@CallerSensitive
public Field getDeclaredField(String name)
throws NoSuchFieldException, SecurityException {
...
}
//2.获取方法
//(1).getMethod name为方法名,因为重载的缘故根据后面的可变长参数来指定特定的方法
@CallerSensitive
public Method getMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
...
}
//(2).getMethods()
@CallerSensitive
public Method[] getMethods() throws SecurityException {
...
}
//(3)getDeclaredMethods()
@CallerSensitive
public Method[] getDeclaredMethods() throws SecurityException {
。。。
}
//(4).getDeclaredMethod()
@CallerSensitive
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
...
}
//3.获取构造函数
@CallerSensitive
public Constructor<T> getConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException
{
}
@CallerSensitive
public Constructor<?>[] getConstructors() throws SecurityException {
}
@CallerSensitive
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException
{
...
}
@CallerSensitive
public Constructor<?>[] getDeclaredConstructors() throws SecurityException {
}
//4.获取所实现的接口
public Class<?>[] getInterfaces() {
...
}
public Type[] getGenericInterfaces() {
}
//5.获取父类
public Type getGenericSuperclass() {
...
}
//6.获取注解
public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
}
public Annotation[] getAnnotations() {
return AnnotationParser.toArray(annotationData().annotations);
}
public <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass) {
Objects.requireNonNull(annotationClass);
return (A) annotationData().declaredAnnotations.get(annotationClass);
}
public Annotation[] getDeclaredAnnotations() {
return AnnotationParser.toArray(annotationData().declaredAnnotations);
}
//7.获取类中定义的类和嵌套接口
@CallerSensitive
public Class<?>[] getClasses() {
...
}
@CallerSensitive
public Class<?>[] getDeclaredClasses() throws SecurityException {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), false);
}
return getDeclaredClasses0();
}
//8.获取当前类的加载器
@CallerSensitive
@ForceInline // to ensure Reflection.getCallerClass optimization
public ClassLoader getClassLoader() {
ClassLoader cl = getClassLoader0();
if (cl == null)
return null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ClassLoader.checkClassLoaderPermission(cl, Reflection.getCallerClass());
}
return cl;
}
//9.其他
public Module getModule() {
return module;
}
public String getName() {
String name = this.name;
return name != null ? name : initClassName();
}
public Package getPackage() {
if (isPrimitive() || isArray()) {
return null;
}
ClassLoader cl = getClassLoader0();
return cl != null ? cl.definePackage(this)
: BootLoader.definePackage(this);
}
public String getPackageName() {
...
}
//Finds a resource with a given name.
@CallerSensitive
public URL getResource(String name) {
...
}
@CallerSensitive
public InputStream getResourceAsStream(String name) {}
}
public final class URL implements java.io.Serializable {
/**
* The protocol to use (ftp, http, nntp, ... etc.) .
* @serial
*/
private String protocol;
/**
* The host name to connect to.
* @serial
*/
private String host;
/**
* The protocol port to connect to.
* @serial
*/
private int port = -1;
/**
* The specified file name on that host. {@code file} is
* defined as {@code path[?query]}
* @serial
*/
private String file;
/**
* The query part of this URL.
*/
private transient String query;
/**
* The authority part of this URL.
* @serial
*/
private String authority;
/**
* The path part of this URL.
*/
private transient String path;
/**
* The userinfo part of this URL.
*/
private transient String userInfo;
/**
* # reference.
* @serial
*/
private String ref;
...
}
代码转载自:
*****https://geek-docs.com/java/java-url/g_url-class-java-examples.html************
// Java program to demonstrate working of URL
// Importing required classes
import java.net.MalformedURLException;
import java.net.URL;
// Main class
// URL class
public class GFG {
// Main driver method
public static void main(String[] args)
throws MalformedURLException
{
// Creating a URL with string representation
URL url1 = new URL(
"https://www.google.co.in/?gfe_rd=cr&ei=ptYq"
+ "WK26I4fT8gfth6CACg#q=geeks+for+geeks+java");
// Creating a URL with a protocol,hostname,and path
URL url2 = new URL("http", "www.geeksforgeeks.org",
"/jvm-works-jvm-architecture/");
URL url3 = new URL(
"https://www.google.co.in/search?"
+ "q=gnu&rlz=1C1CHZL_enIN71"
+ "4IN715&oq=gnu&aqs=chrome..69i57j6"
+ "9i60l5.653j0j7&sourceid=chrome&ie=UTF"
+ "-8#q=geeks+for+geeks+java");
// Printing the string representation of the URL
System.out.println(url1.toString());
System.out.println(url2.toString());
System.out.println();
System.out.println(
"Different components of the URL3-");
// Retrieving the protocol for the URL
System.out.println("Protocol:- "
+ url3.getProtocol());
// Retrieving the hostname of the url
System.out.println("Hostname:- " + url3.getHost());
// Retrieving the default port
System.out.println("Default port:- "
+ url3.getDefaultPort());
// Retrieving the query part of URL
System.out.println("Query:- " + url3.getQuery());
// Retrieving the path of URL
System.out.println("Path:- " + url3.getPath());
// Retrieving the file name
System.out.println("File:- " + url3.getFile());
// Retrieving the reference
System.out.println("Reference:- " + url3.getRef());
}
}
运行结果:
https://www.google.co.in/?gfe_rd=cr&ei=ptYqWK26I4fT8gfth6CACg#q=geeks+for+geeks+java
https://www.geeksforgeeks.org/jvm-works-jvm-architecture/
Different components of the URL3-
Protocol:- https
Hostname:- www.google.co.in
Default port:- 443
Query:- q=gnu&rlz=1C1CHZL_enIN714IN715&oq=gnu&aqs=chrome..69i57j69i60l5.653j0j7&sourceid=chrome&ie=UTF-8
Path:- /search
File:- /search?q=gnu&rlz=1C1CHZL_enIN714IN715&oq=gnu&aqs=chrome..69i57j69i60l5.653j0j7&sourceid=chrome&ie=UTF-8
Reference:- q=geeks+for+geeks+java