假设现在上面的数据是以二次探测的方式来进行存放的,现在让你求:

现在找1:直接就能找到----->次数是1

现在找4:直接就可以找到---->次数是1

现在找14:先得到4的下标,发现不是14向后找,这里面用了两次

现在找24::先得到4的下标,发现不是24向后找,这里面用了3次

总共找的次数:1+1+2+3+1=8

1)查找成功的平均长度:查找成功的次数/有效数据的长度=8/5;

2)查找不成功的平均长度:

已经存在的数据:查找的这个数位置开始前一个向后走几步到空格?2+4+3+2+2=13

没有存在的数据就是1;

0-->1

1--->2

2--->1

3---->1

4---->4

14---->3

24----->2

7------>1

8------>1

9------>2

18/10=1.8;

查找不成功的次数/数组的长度

1.反射

1)反射的定义:

1.1)Java中的反射,是指在运行过程中,对于任意的一个类,都可以知道这个类的所有属性和方法;对于任意一个对象,都可以调用它的任意的一个方法和属性,那么既然可以拿到,我们就可以修改部分类型信息;这种动态获取信息以及动态调用对象的方法的功能称之为Java语言的反射机制

1.2)所有有关于反射相关的类和相关的包都在java.lang.reflect包下面

2)反射中涉及到的一些常见的类-----重要

反射中在哪里用到,介绍一下(面试--框架)

主要用途:

1)在我们日常的第三方应用开发过程中,通常会遇到某个类的成员变量,方法或者属性是私有的或只是系统应用对应开放,这时候我们就可以通过反射获取所需的私有的成员或者方法

2)反射最重要的就是开发各种应用型框架,比如在Spring中,我们将所有的类Bean交给Spring容器进行管理,无论是XML配置Bean还是注解配置,当我们从容器中获取Bean来进行依赖注入的时候,容器会读取配置,而配置中给的就是类的信息,spring根据这些信息,需要创建那些bean,spring就动态的创建这些类

1)Class类:代表类的实体,在运行的java程序中表示类和接口

2)Field类:代表类的成员变量/类的属性

3)Method类:代表类的方法

4)Constructor类,它是代表类的构造方法

Java被编译之后,生成了.class文件(此时在磁盘上面),我们要把这个.class运行到JVM的时候,需要通过JAVA命令来进行运行,此时JVM就会要去解读.class文件,被编译后的java文件.class最终也被JVM解析成一个类,这个对象就是java.lang.Class,当程序在运行的时候,每一个类就变成了Class对象的一个实例。这样当程序正在运行的时候,我们通过java的反射机制应用到这个实例,就可以去获得甚至去改变这个类的属性和动作,是这个类称为一个动态的类;

class Student {//此时构造方法是私有的,我们要想创建对象,只能在类内创建,通过方法返回给类外private int age=18;private String name="bit";public Student(){System.out.println("我是这个类中的不带有参数的构造方法");}private Student(String name, int age){this.name=name;this.age=age;System.out.println("我是这个类中一个私有的构造方法");}private void start(String str){System.out.println("我是这个类中的带参数的普通方法"+str);}private void run(){System.out.println("我是这个类中的不带有参数的私有方法");}@Overridepublic String toString() {return "Student{" +"age=" + age +", name='" + name + '\'' +'}';}}

1)获取当前的Class对象(通过反射来获取类对象),此时有三种方式

1)通过Class.forName(里面是路径)方法

Class<?> C1=Class.forName("Student");//包名.类名
Class<?> C2= Student.class;
Student student=new Student();
Class<?> C3=student.getClass();
System.out.println(C1==C2);
System.out.println(C2==C3);
不管是用哪种方式来获取Class对象,这里面的打印结果都是True,说明类对象只有一个

2)通过类名.Class返回一个实例

3)先类创建实例,再通过引用.getClass()来进行返回

        //1.根据包全限定类名:Class.forName("类的全路径名");Class<?> StudentClass1=Class.forName("Demo.Student");//2.使用.class方法Class<?> StudentClass2=Student.class;//3.通过先进行创建对象的实例,在进行获取类对象Student student=new Student();Class<?> StudentClass3=student.getClass();

2.创建对象

类对象的引用.newInstance() 创建一个对象,也就是说通过类对象的newInstance方法来获取学生实例

//1.先进行获取到类的类对象
Class<?> C1=Class.forName("Student");
//2.通过反射创建这个类的实例
Student lijiawei= (Student) C1.newInstance();//最重要进行强制类型转换,这样就可以实例化一个对象 System.out.println(lijiawei);
//3.访问一些信息
System.out.println(lijiawei);
打印结果:我是这个类中的不带有参数的构造方法
Student{age=18, name='bit'}

要不就直接通过类对象的实例调用newInstance()创建这个对象的实例

要不就先获取到构造方法,通过调用constructer.newInstance方法传入相关的构造参数来进行创建实例

3.获取类中的构造器的方法:

1)getConstructor(Class......<?> parameterTypes)获得该类中与参数类型相匹配的公有的构造方法

2)getConstructors()获取该类的所有的所有的构造方法

3)getDeclaredConstructor(Class<?> parameterTypes)获取该类中与参数类型相匹配的构造方法//即可以获取到公有构造方法,也可以获取到私有构造方法

4)如果在其中获取到了私有的构造方法,我们还是需要调用一下构造器引用.setAccessible()方法,将里面的参数设置成true

5)getDeclaredConstructors() 获取该类的所有构造方法

   public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {//现在我们想获取到Student类的私有构造方法//1.先获取到类对象Class<?> ClassStudent=Class.forName("Demo.Student");//2.获取到构造方法Constructor<Student> constructor= (Constructor<Student>) ClassStudent.getConstructor(String.class,int.class);//里面传入构造方法具体的参数类型.class//3.调用构造方法,传入相应的参数,创建对应的实例Student student=constructor.newInstance("李佳伟",90);System.out.println(student);//上面的代码直接运行会报错,因为我们调用的是私有的构造方法,为了体现封装的安全性,我们应该再加上一条语句}

现在这么写就好了:

  public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {//现在我们想获取到Student类的私有构造方法//1.先获取到类对象Class<?> ClassStudent=Class.forName("Demo.Student");//2.获取到构造方法Constructor<Student> constructor= (Constructor<Student>) ClassStudent.getDeclaredConstructor(String.class,int.class);//里面传入构造方法具体的参数类型.class//3.调用构造方法,传入相应的参数,创建对应的实例constructor.setAccessible(true);//可以使用构造方法Student student=constructor.newInstance("李佳伟",90);System.out.println(student);//上面的代码直接运行会报错,因为我们调用的是私有的构造方法,为了体现封装的安全性,我们应该再加上一条语句}

4.反射私有的属性(可以获取私有的,获取公开的)

1)getField(String name) 获得某一个共有的属性对象

2)getFields()获取到所有的共有的属性对象

3)getDeclaredField(String name)获取到某一个属性对象,返回值是一个Field对象

4)getDeclaredFields()获取到所有的属性对象

  //现在我们想获取到Student类的私有构造方法//1.先获取到类对象Class<?> ClassStudent=Class.forName("Demo.Student");//2.获取到构造方法构造对象Constructor<?> constructor=ClassStudent.getDeclaredConstructor(String.class,int.class);constructor.setAccessible(true);Student student=(Student)constructor.newInstance("李佳伟",12);//3.获取到类里面的字段Field filed1=ClassStudent.getDeclaredField("name");//里面填写字段名Field filed2=ClassStudent.getDeclaredField("age");filed1.setAccessible(true);filed2.setAccessible(true);//4.进行修改私有字段和属性filed1.set(ClassStudent,"张志超");filed2.set(ClassStudent,81);//第一个参数填写这个对象的引用,第二个参数写要修改成为的具体的字段名System.out.println(filed1);System.out.println(filed2);

5.反射类中的方法

1)获取某个类中共有的方法:getMethod(),里面的参数是方法名,参数类型.class,最终返回的是Method对象
2)获取到该类中所有的方法:getMethods()
3)获取到该类中的某一个方法getDeclaredMethod(String name,Class....<?> parameterTypes)
4)获取到该类中的所有方法:getDeclaredMethods();
method.invoke(对象名,字段值)我们最重要调用这个方法来进行调用我们获取到的方法
   //1.先进行获取到类对象Class<?> classStudent=Student.class;//2.获取到私有的构造方法Constructor<?> constructor= classStudent.getDeclaredConstructor(String.class,int.class);//3.创建具体的对象constructor.setAccessible(true);Student student=(Student)constructor.newInstance("张中军",90);//4.获取到对应的方法Method method= classStudent.getDeclaredMethod("start",String.class);method.setAccessible(true);//5.调用对应的获取到的方法method.invoke(student,"sb");

2.枚举

1)背景以及定义:

枚举是在JDK1.5之后进行引入的,目的用途是将一组常量组织起来,在这之前表示一组常量通常使用定义常量的方式例如:

public static final int RED=1;

public static final int GREEN=2;

public static final int BLACK=3;

但常量枚举有一个不好的地方,例如假设现在正好有一个数字1,但是他可能会被误认为是RED,现在我们可以直接使用枚举来进行组织,这样一来就拥有了枚举类型而不是一个普通的数字1;

public enum TestEnum{RED,BLACK,GREEN;public static void main(String[] args]{System.out.println(TestEnum.RED);//在类外要通过类名.的方式System.out.println(BLACK);}}此时打印出来的值就是RED,BLACK
public enum TestEnum{RED,BLACK,GREEN;public static void main(String[] args){TestEnum testEnum=TestEnum.BLACK;switch (testEnum){case RED:System.out.println("red");break;case BLACK:System.out.println("black");break;case GREEN:System.out.println("green");break;}}}

2.Enum中的常见方法(自己写的枚举类,默认继承了一个抽象类Enum,public abstract class<E extends Enum<E>> implements Comparable<E>,Serializable;

1)values()以数组的形式返回枚举类型的所有成员

2)ordinal()获取到枚举成员的索引位置--------在Enum类里面

3)valueOf()将普通字符串转化成枚举实例

4)compareTo()比较两个枚举成员定义的顺序,默认是通过索引来进行比较的

public enum TestEnum{RED,BLACK,GREEN,WHITE;public static void main(String[] args) {TestEnum[] arr1=TestEnum.values();for(int i=0;i< arr1.length;i++){System.out.println(arr1[i]+arr[i].ordinal());}//把字符串变成对应的枚举对象TestEnum testEnum= TestEnum.valueOf("RED");System.out.println(testEnum);REDSystem.out.println(RED.compareTo(BLACK));System.out.println(BLACK.compareTo(WHITE));}
}

1)枚举的构造方法默认是私有的

 2)枚举类是不可以被继承的(TestEnum不可被继承)

1)既然枚举的构造方法是私有的,那么我们是否可以通过反射来获取枚举对象的实例呢?

public enum TestEnum{RED("hello",1),BLACK("world",2),GREEN("l want",3),WHITE("kkkk",4);public String color;public int origin;private TestEnum(String color,int origin)
//此时的自己构造方法默认是私有的{
//这里面会默认帮助父类进行构造,会默认super(),默认执行这个构造方法this.color=color;this.origin=origin;}public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Class<Enum> S1= (Class<Enum>) Class.forName("TestEnum");
Constructor<Enum> constructor=S1.getDeclaredConstructor(String.class,int.class);
//枚举的构造方法是私有的,所以要把参数设置成true
constructor.setAccessible(true);
TestEnum testEnum= (TestEnum) constructor.newInstance("BLUE",23);
//构造方法里面再写"hhh",89;那么这时还是会报错的System.out.println("枚举对象是"+testEnum);}
}
这段代码时会报错的,他的报错的意思是没有这样的构造方法
但是在我们所写的代码中,是存在这样的构造方法的,那怎么会没有呢?

原因是我们自己所写的枚举类默认是继承于上面的一个抽象类的,而这个抽象类的构造方式是含有两个参数的,所以在我们自己所写的枚举类型中,我们应该先要帮助父类进行构造

Constructor<Enum> constructor=S1.getDeclaredConstructor(String.class,int.class,String.class,int.class);

// TestEnum testEnum= (TestEnum) constructor.newInstance("BLUE",23,"bit",99)

//其实本质上TestEnum是四个构造参数,构造方法里面后面再写"hhh",89;那么这时还是会报错的,先帮助父类进行构造

1)在咱们的反射里面的newInstance方法里面会进行判断,如果是枚举类型,是不可以创建实例的

2)所以我们进行总结,枚举类型是非常安全的,我们无法通过反射来进行获取到枚举类型的实例对象

如何设置一个线程安全的单例模式呢?

1)构造方法私有化

2)实例化的变量引用私有化

3)获取实例的方法共有

把构造方法设置成私有的,在类里面之创建一个实例,并进行返回;通过公开方法来获取到一个实例;

1)设计饿汉模式和懒汉模式,里面的字段属性一定要是private static 防止在类外被访问到,除了获取实例的方法之外设置成public之外;

public class Singleton {Object object = new Object();private Singleton() {};private volatile static Singleton singleton = null;public static Singleton getInstance() {if (singleton == null) {synchronized (Object.class) {if (singleton == null) {return new Singleton();}}}return singleton;}class Singleton{private Singleton(){};private static final Singleton singleton=new Singleton();public  static Singleton getInstance(){return singleton;}
}

2)通过静态内部类来实现一个单例模式:

class Singleton{private Singleton(){};private static class User{private static final Singleton singleton=new Singleton();}public static Singleton getInstance(){return User.singleton;}}
}
class TestEnum{public static void main(String[] args) {Singleton singleton=Singleton.getInstance();Singleton singleton1=Singleton.getInstance();System.out.println(singleton1==singleton);}
}

3)通过枚举来实现一个单例模式:使用枚举实现单例模式利用了枚举的特性

public enum TestEnum{RED;public  static TestEnum getInstance(){return RED;}public static void main(String[] args) {TestEnum testEnum1=TestEnum.getInstance();TestEnum testEnum=TestEnum.getInstance();System.out.println(testEnum==testEnum1);}
}

Java中的反射和枚举相关推荐

  1. 浅说Java中的反射机制(一)

    在学习传智播客李勇老师的JDBC系列时,会出现反射的概念,由于又是第一次见,不免感到陌生.所以再次在博客园找到一篇文章,先记录如下: 引用自java中的反射机制,作者bingoideas.(()为我手 ...

  2. Java 中使用反射来创建对象、调用方法

    Java 中使用反射来创建对象.调用方法 反射创建对象 反射调用方法 反射调用私有方法 反射调用可变参私有方法 反射调用的方法自身可以抛出异常的情形   假设已有下面的类: import java.l ...

  3. java代码安全检测机制_全面解析:java中的反射机制,内含代码验证解析

    什么是反射? 在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的方法的功 ...

  4. 深入理解Java中的反射技术

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

  5. formdata 接受参数中带有class 对象_浅析JAVA中的反射机制及对Servlet的优化

    今天来聊聊java中的反射机制,工作以后发现很多东西动不动就要使用反射或者动态代理,如果不能很好的理解反射,那么对于动态代理等一些重要的设计模式就会有种不够通透的感觉. 所谓的反射,就是在运行状态中, ...

  6. java中的反射机制是什么

    给大家介绍一下java中的反射机制,java中反射机制更体现出了java的灵活性.多态.和类之间的耦合性. 1:反射是一种间接操作目标对象的机制,只要给定类的名字,就可以通过反设机制获取所有的类信息. ...

  7. Java中的反射机制详讲

    Java中的反射机制详讲 1.反射机制_介绍_Class对象获取 2.反射机制_动态操作_构造器_方法_属性 3.动态编译_DanamicCompile_反射调用main方法问题 好文推荐:排序.查找 ...

  8. Java中的反射如何理解——精简

    目录 引言 反射概念 反射获取类对象 反射获取构造器对象 获取构造器对象并使用 反射获取成员变量对象 反射获取方法对象 反射获取成员方法并使用 引言 经过前面的学习,相信大家已经能够对网络编程有了一定 ...

  9. 什么是java中的反射?反射的一些常用方法

    一.什么是java中的反射 Java 反射,就是在运行状态中. 获取任意类的名称.package信息.所有属性.方法.注解.类型.类加载器等 获取任意对象的属性,并且能改变对象的属性 调用任意对象的方 ...

最新文章

  1. Spring MVC拦截器+注解方式实现防止表单重复提交
  2. 10.ASCII码对照
  3. python手机销售系统详细设计_数据库详细设计文档 .doc
  4. python调用父类对象的几个方法
  5. php使用openssl进行Rsa长数据加密,解密保存问题
  6. NgRx使用CreateSelector组装复合Selector
  7. udp包大小选折及原因(mtu)
  8. asp.net listview 字段太多 滚动条_高考英语阅读理解生僻单词太多怎么办?十大招数帮到你...
  9. input 对伪元素(:before :after)的支持情况
  10. java的写法作文,RxJava系列文章(二) - 网络图片添加水印RxJava写法
  11. Python 函数参数传递的困惑
  12. 如何破解无法炸开的CAD加密图纸
  13. 根据WSDL文件生成JAVA代码
  14. iOS 开发者应该知道的 ARM 结构(转自apple4us)
  15. 捕获组合键 键盘组合键
  16. 等比缩放公式_iPhone屏幕适配,等比缩放
  17. SQL面试题:经典50例
  18. 马斯克把飞船方向盘用在特斯拉新车上!乞丐版80万起
  19. logging日志管理
  20. pow ( )【C语言库函数源代码】

热门文章

  1. 用计算机算出爸爸我爱你,爸爸,我爱你。
  2. C语言中字符串用strcmp和==比较的问题
  3. 大数据算法 chap-2 亚线性算法
  4. 科技节编程大赛三等奖作品——李白杨
  5. 功能测试——抓包工具(fiddler)
  6. 解决问题就是有成就感
  7. 被误解最大的基础学科——统计学,到底是个啥?
  8. python考试题目及答案-python考试题库
  9. blt功能_C++中BitBlt的使用方法详解
  10. 6月书讯(上)| 浅夏读新书,与世间万物一起成长