java基础九反射和匿名内部类
反射是框架设计的灵魂
(使⽤的前提条件:必须先得到代表的字节码的Class,Class类⽤于表⽰.class⽂件(字节码))
⼀、反射的概述
class是⼀切反射的根源,JAVA反射机制是在运⾏状态中,对于任和⼀个类,通过反射都能够知道这个类的所有属性和⽅法;对于任意⼀个对象,都能够调⽤它的任意⼀个⽅法和属性;这种动态获取的信息以及动态调⽤对象的⽅法的功能称为java语⾔的反射机制
要想解剖⼀个类,必须先要获取到该类的字节码⽂件对象。⽽解剖使⽤的就是Class类中的⽅法.所以先要获取到每⼀个字节码⽂件对应的Class类型的对象.
本⼈简单理解就是⽤⼀段字符串直接调取类及其该类的⽅法。
反射的作⽤
通过反射访问java对象的属性,⽅法,构造⽅法等
反射机制的相关类
与Java反射相关的类如下:
类名⽤途
Class类代表类的实体,在运⾏的Java应⽤程序中表⽰类和接⼝
Field类代表类的成员变量(成员变量也称为类的属性)
Method类代表类的⽅法
Constructor类代表类的构造⽅法
注意:都是Object类的⼦类
反射的基本机制
: 可以根据⼀个“类全名字符串” ,获得代表这个类的class对象,然后根据这个class对象构造出这个类的真正实例对象
可⽤Class.forName(“类的包名”)这个⽅法得到⼀个Class类
String className = "cn.flect.demo.SerivceOne"; // 通常这个字符串常常存在⽂件当中,⽤io流调⽤
Class<?> forName = Class.forName(className); // 根据类名字符串“SerivceOne”获取class对象
SerivceOne o = (wInstance(); // ⽤class对象构造出这个类SerivceOne的实例对象
o.say();
然后该反射常常应⽤于接⼝
⽐如这⾥我们有⼀个接⼝Fuck还有其 实现类FuckImpl,然后约定好将该实现类的完整包名保存⼊⽂件当中。
然后我们调⽤该接⼝的时候就可以这样
public class Menu {
public static void main(String[] args) throws Exception {
/
/ 从约定的⽂件中读取所需类的实现类全名
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("f:/a.txt")));
String ClassName = br.readLine(); /将⽂件中的按⾏包名输出
Class<?> forName = Class.forName(ClassName); // forName代表的是serviceClassName字符串所指定的类的类class模板
// 根据类全名构造这个service实现类的实例
Fuck fuck = (Fuck) wInstance();`}}
三、通过反射获取类的构造⽅法、⽅法以及属性
Class<?> forName = Class.forName(ClassName);
// 根据类全名构造这个service实现类的实例
Fuck fuck = (Fuck) wInstance();`
//methodName存的是⽅法名的字符串,从forName这个class模板中获取到指定的⽅法
Method Method(methodName) ;
//让Method在对象上执⾏,()中写对象和参数
Object invoke=method.invoke(fuck,12);
-------------------------------------------------------------------------
//如果存在同名⽅法,则有参数的需要这样输⼊
Method Method(methodName,String.Class) ;
Object invoke=method.invoke(fuck,12);
配置⽂件⽤到的⼩⼯具Properties()
Properties中的主要⽅法
(1)load(InputStream inStream)
这个⽅法可以从.properties属性⽂件对应的⽂件输⼊流中,加载属性列表到Properties类对象。如下⾯的代码:
Properties pro = new Properties();
FileInputStream in = new FileInputStream("a.properties");
pro.load(in);
in.close();
(2)store(OutputStream out, String comments)
这个⽅法将Properties类对象的属性列表保存到输出流中。如下⾯的代码:
FileOutputStream oFile = new FileOutputStream(file, "a.properties");
pro.store(oFile, "Comment");
oFile.close();
如果comments不为空,保存后的属性⽂件第⼀⾏会是#comments,表⽰注释信息;如果为空则没有注释信息。注释信息后⾯是属性⽂件的当前保存时间信息。
(3)getProperty/setProperty
这两个⽅法是分别是获取和设置属性信息。
反射与属性配置⽂件的加载
Properties props = new Properties();
//加载xx.properties属性配置⽂件
props.load(ClassLoader().getResourceAsStream("xx.properties"));
//取配置参数
String value = Property("key");
Class<?> forName = Class.forName(value); // forName代表的是serviceClassName字符串所指定的类的类class模板
// 根据类全名构造这个service实现类的实例
Fuck fuck = (Fuck) wInstance();`
然后应该在同个包中直接建⽴***file***
内容是
key=value的形式
ClassName=fuckMan
Method=fuck
匿名内部类
匿名内部类也就是没有名字的内部类
正因为没有名字,所以匿名内部类只能使⽤⼀次,它通常⽤来简化代码编写
但使⽤匿名内部类还有个前提条件:必须继承⼀个⽗类或实现⼀个接⼝
实例1:不使⽤匿名内部类来实现抽象⽅法
abstract class Person {
public abstract void eat();
}
class Child extends Person {
public void eat() {
System.out.println("eat something");
}
}
public class Demo {
public static void main(String[] args) {
Person p = new Child();
p.eat();
}
}
运⾏结果:eat something
可以看到,我们⽤Child继承了Person类,然后实现了Child的⼀个实例,将其向上转型为Person类的引⽤但是,如果此处的Child类只使⽤⼀次,那么将其编写为独⽴的⼀个类岂不是很⿇烦?
这个时候就引⼊了匿名内部类
实例1:不使⽤匿名内部类来实现抽象⽅法
abstract class Person {
public abstract void eat();
}
class Child extends Person {
public void eat() {
System.out.println("eat something");
}
}
public class Demo {
public static void main(String[] args) {
Person p = new Child();
p.eat();
}
}
运⾏结果:eat something
可以看到,我们⽤Child继承了Person类,然后实现了Child的⼀个实例,将其向上转型为Person类的引⽤但是,如果此处的Child类只使⽤⼀次,那么将其编写为独⽴的⼀个类岂不是很⿇烦?
这个时候就引⼊了匿名内部类
实例2:匿名内部类的基本实现
abstract class Person {
public abstract void eat();
}
public class Demo {
public static void main(String[] args) {
Person p = new Person() {
public void eat() {
System.out.println("eat something");
}
};
p.eat();
}
}
运⾏结果:eat something
可以看到,我们直接将抽象类Person中的⽅法在⼤括号中实现了这样便可以省略⼀个类的书写
并且,匿名内部类还能⽤于接⼝上
实例3:在接⼝上使⽤匿名内部类
interface Person {
public void eat();
}
public class Demo {
public static void main(String[] args) {
Person p = new Person() {
public void eat() {
System.out.println("eat something");
}
};
p.eat();
}
java接口有没有构造方法}
运⾏结果:eat something
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论