反射
反射可以在运行中知晓任意类的任意属性和方法。这种动态获取信息的功能称之为反射。
小栗子
package moudle2;
public class Test17 {
public static void main(String[] args) {
Test17 t17 = new Test17();
System.out.println(t17.getClass());
}
}
程序运行结果:
class moudle2.Test17
上述栗子中,Test17类使用了继承自Object类的getClass()方法。
打印结果是Test17类的完整的 "包.类" 名。(也叫完整名称)
getClass()方法定义如下:
public final native Class<?> getClass()
final:无法被子类重写的方法。
native:调用底层类库,底层使用其他语言实现。
返回类型:Class,一个名为Class的类。
泛型:通配符,接收任意类型。
认识Class类
getClass()方法返回的是一个Class类,Class类是Java反射的源头。
Class类表示一个类自身,通过Class类可以完整地获得一个类的完整结构,包括:方法,属性,完整名称,甚至包括其父类和实现的接口。
三种实例化Class类对象的方法
栗子:
package moudle2;
public class Test17 {
public static void main(String[] args) throws ClassNotFoundException {
Test17 t17 = new Test17();
System.out.println(Class.forName("moudle2.Test17"));//Class类的静态方法,传参为完整类名
System.out.println(t17.getClass());//继承自Object的getClass()方法
System.out.println(Test17.class);//一种特殊的实例化 类.class
}
}
程序运行结果:
class moudle2.Test17
class moudle2.Test17
class moudle2.Test17
上述三种方法都是一样的,但第一种Class.forName()的方式较为常见且更具灵活性。
但可能会出现ClassNotFoundException异常
Class类的使用
Clss类的部分常用方法:
方法 | 类型 | 描述 |
---|---|---|
public static Class<?> forName(String className) throws ClassNotFoundException | 静态方法 | 传入完整类名返回实例化Class对象 |
public String getName() | 普通方法 | 获取一个类的完整名称 |
public T newInstance() throws InstantiationException, IllegalAccessException | 普通方法 | 返回Class定义的类实例化对象 |
public Class<?>[] getInterfaces() | 普通方法 | 获取一个类实现的全部接口 |
public native Class<? super T> getSuperclass() | 底层方法 | 获取一个类的父类 |
public String getName()
获取一个类的完整名称
栗子:
package moudle2;
public class Test17 {
public static void main(String[] args) throws ClassNotFoundException {
Test17 t17 = new Test17();
System.out.println(Class.forName("moudle2.Test17").getName());
}
}
程序运行结果:
moudle2.Test17
public T newInstance()
创建并返回一个类的实例化对象
栗子:
package moudle2;
public class Test17 {
public static void main(String[] args) {
try {
Class clazz = Class.forName("moudle2.Noodle");//完整名称
Noodle o = (Noodle) clazz.newInstance();//创建Noodle类的实例 等价于 Noodle o =new Noodle();
o.eat();//向下转型是为了调用Noodle类的特有方法 eat
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Noodle {
private String name = "面条";
public Noodle() {
}
public void eat() {
System.out.println("吃" + name);
}
}
程序运行结果:
吃面条
注意被实例化的类必须存在无参构造。(隐式显式都可以,但必须存在无参构造)
不存在无参构造的栗子如下:
package moudle2;
public class Test17 {
public static void main(String[] args) {
try {
Class clazz = Class.forName("moudle2.Noodle");
Noodle o = (Noodle) clazz.newInstance();//创建Noodle类的实例 等价于 Noodle o =new Noodle();
o.eat();//向下转型是为了调用Noodle类的特有方法 eat
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Noodle {
private String name = "面条";
public Noodle(String name) {//显式定义了有参构造,默认的隐式无参构造被覆盖
this.name = name;
}
public void eat() {
System.out.println("吃" + name);
}
}
程序运行结果:
java.lang.InstantiationException: moudle2.Noodle
at java.lang.Class.newInstance(Class.java:427)
at moudle2.Test17.main(Test17.java:7)
Caused by: java.lang.NoSuchMethodException: moudle2.Noodle.<init>()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.newInstance(Class.java:412)
... 1 more
因此,建议每个自定义的类必须显式定义无参构造
public Class<?>[] getInterfaces()
获取一个类实现的所有接口
栗子:
package moudle2;
public class Test17 {
public static void main(String[] args) {
try {
Class clazz = Class.forName("moudle2.Noodle");
Class[] interfaces = clazz.getInterfaces();
for (Class a : interfaces) {
System.out.println(a);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Noodle implements Hot,Delicious,Cheap {}
interface Hot{}
interface Delicious{}
interface Cheap{}
程序运行结果:
interface moudle2.Hot
interface moudle2.Delicious
interface moudle2.Cheap
public native Class<? super T> getSuperclass()
获取一个类的父类
栗子:
package moudle2;
public class Test17 {
public static void main(String[] args) {
try {
Class clazz = Class.forName("moudle2.Noodle");
Class a = clazz.getSuperclass();
System.out.println(a);
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Noodle extends Rice {}
class Rice {}
程序运行结果:
class moudle2.Rice
标签:Noodle,Java,拾贝,class,moudle2,Class,初认,public,Test17
From: https://www.cnblogs.com/Ocraft/p/17810856.html