精华内容
下载资源
问答
  • 2021-02-13 01:19:40

    目前我有一个类TransactionData,它只比POJO多一点.我从HTTPServletRequest构建对象.我所做的:

    public class TransactionData

    {

    // ...

    public TransactionData(HttpServletRequest request) throws IOException

    {

    // do actual work here

    }

    }

    这里有很多WTF,最令人不安的是对象TransactionData与HTTPServletRequest紧密耦合.我的想法:使用extract()方法创建一个TransactionDataExtractor接口,以便我可以实现不同的类来构建对象.

    public interface TransactionDataExtractor

    {

    public TransactionData extract();

    }

    但是,如何将构建TransactionData所需的东西传递给每个实现?想到的第一件事就是使用不同的构造函数,如下所示:

    public class TransactionDataExtractorRequest implements TransactionDataExtractor

    {

    private HttpServletRequest httpRequest;

    public TransactionDataExtractorRequest(HttpServletRequest httpRequest)

    {

    this.httpRequest = httpRequest;

    }

    public TransactionData extract()

    {

    // do whatever is required

    }

    }

    但在这种情况下,每当我需要构建一个新的TransactionData对象时,我必须创建一个新的TransactionDataExtractorRequest.我完全不喜欢隐含的依赖.

    我能想到的另一个选择是将一个Object参数传递给extract()并在需要时抛出它,放弃类型安全并引入大量的锅炉板丑陋的代码

    public TransactionData extract(Object o)

    {

    HttpServletRequest h;

    if (o instanceof HttpServletRequest)

    {

    h = (HttpServletRequest)o;

    }

    //...

    }

    我不知道自己是否已经说清楚了.我觉得我错过了一些东西,我知道解决方案非常简单,但我无法掌握它.

    有什么想法吗?

    TIA.

    编辑:问题甚至可能是我的预感完全错误,我可以毫不后悔地解雇它

    更多相关内容
  • 在学习群里面看到一位同学问——一个类中可以定义多个空参数构造方法吗 我当是在想应该不行的吧,然后看到那个问问题的同学说:“可以再定义局部类的空参构造方法”,然后自己看了一下关于局部类的知识确实阔以,...
  • 场景: flink中的算子在初始化时想添加一些外部参数,这些外部参数只有在main启动时才会传入,可能数据的值不同 自已创建了一个类继承了RichFlatMapFunction<Row, Row> implements Serializable,实现了...

    场景: flink中的算子在初始化时想添加一些外部参数,这些外部参数只有在main启动时才会传入,可能数据的值不同

    自已创建了一个类继承了RichFlatMapFunction<Row, Row> implements Serializable,实现了RichFlatMapFunction的flatMap方法,像下面的示例一样

    public class FlatFunction1 implements FlatMapFunction<Row, Row> {
      private String a;
      private String b;
    // 写了一个带参数的构造器,这样初始化这个算子时,就会在构造器中初始化一些参数,
      public FlatFunction1(Object c){
      	//用c初始化 a,b
    	}
      @Override
      public void flatMap(String value, Collector<String> out) {
        //执行逻辑
      }
    }
    

    通过带参数的构造函数,在算子初始化就可以对算子内部的字段初始化

    警告:我这些参数是算子内私有的,也就是private,但是不能写成static修饰的,否则如果是像k8s托管flink集群的这种方式,每一个task虽然都初始化了,但是执行时初始化后的字段还是null

    展开全文
  • Review后看到标题让我十分羞愧自己语文功底太差,估计...请见谅......我还特地把这句写回开头了...... ...这次是“泛型的类型能否有带参数的约束方式”。 具体想法很简单,在我使用泛型的时候,我发...

    Review后看到标题让我十分羞愧自己语文功底太差,估计...请见谅......我还特地把这句写回开头了......

     

     

    问题

    前天遇到的一个问题,所以在MSDN发了个问,刚也丰富了下问题,关于泛型的。

    最近用EF尝试DDD常常有些奇怪的想法,比如“EF的Model First能否添加泛型支持”。这次是“泛型的类型能否有带参数的约束方式”。

    具体想法很简单,在我使用泛型的时候,我发现我需要实例化一个类型参数:

    1 class MyClass<T>
    2 {
    3     public MyClass1()
    4     {
    5         this.MyObject = new T();
    6     }
    7 
    8     T MyObject { get; set; }
    9 }

    当然,上面会报错

    错误内容是T没有一个new约束(new constraint),查阅下MSDN,得到了泛型的类型参数的new约束的内容

    所以接下来正确的代码就是:

     1 class MyClass<T>
     2     where T : new()
     3 {
     4     public MyClass1()
     5     {
     6         this.MyObject = new T();
     7     }
     8 
     9     T MyObject { get; set; }
    10 }

     

    然后,后来我发现,我需要根据参数来创建新的对象,而且该方法在泛型的构造函数中实现最合适,所以我希望有这样的代码:

     1 class MyClass1<T>
     2     where T : new(string)
     3 {
     4     public MyClass(string request)
     5     {
     6         this.MyObject = new T(request);
     7     }
     8 
     9     T MyObject { get; set; }
    10 }

    可惜这下就错大了,然后查阅泛型的约束方式列表,发现根本没有带参数的构造函数这种约束

     

    所以就发生了我上面在MSDN上问的那个问题,寻求一个“优雅的解决方案”。

     

    一般解决方案就像问题中的回答那样有两种,也是我试过但是很不爽的两种,我们依次看看。

    补充:

    • James.Ying提醒,还有从构造函数传入
    • 由@Choo提醒,用Activator.CreateInstance

     

     

    工厂模式

    首先是Factory Pattern,就是建一个工厂类,先看看代码,这是其中一种写法,请不要纠结在Factory Pattern上:

     1 class MyClass<T, TFactory>
     2     where TFactory : IFactory<T>, new()
     3 {
     4     public MyClass(string request)
     5     {
     6         var factory = new TFactory();
     7 
     8         this.MyObject = factory.New(request);
     9     }
    10 
    11     T MyObject { get; set; }
    12 }
    13 
    14 interface IFactory<T>
    15 {
    16     T New(string request);
    17 }

    实现中你会发现,这样需要为每个派生类或者实例类别创建并维护一个Factory类,那样泛型本身就没那么大意义了,本来就是为了减少类型重用逻辑而采用泛型的

     

     

    抽象基类的静态抽象方法

    如果不想维护多一个类,那么就在目标类本身下手,所以我们可以为目标类创建一个基类:

     1 class MyClass<T>
     2     where T : TBase, new()
     3 {
     4     public MyClass(string request)
     5     {
     6         this.MyObject = T.New(request);
     7     }
     8 
     9     T MyObject { get; set; }
    10 }
    11 
    12 abstract class TBase
    13 {
    14     public abstract static TBase New(string request);
    15 }

    为了防止误人子弟,首先要说在前头的是,这样写是会编译错误的!

    约束上是没错的,但是它报的错误是类似于“T是个类型参数,不能这么用!”('T' is a 'type parameter', which is not valid in the given context)。

     

     

    从构造函数传入

    还有一种基础的做法反而忘记了,由James.Ying提醒想起来,就是从泛型类的构造函数传入。

    class MyClass<T>
        where T : TBase, new()
    {
        public MyClass(T myObject)
        {
            this.MyObject = myObject;
        }
    
        T MyObject { get; set; }
    }

    这种方式使得泛型类简洁多了,把实例化的过程交给了调用者,有点依赖倒置了(其实凡是应该在泛型里实现的而交给了调用者或者继承者都是这样)。

    优点是泛型简单了,缺点就是你无法保证实例化使用的构造函数是T(string)。另外,它可能会降低代码的重用性。假设实例化是有条件地,而且所有派生类的逻辑是统一的,那么还是在泛型基类中实现比较好。

    简单情况下这是对泛型来说最优雅的方式了。

     

     

    Activator.CreateInstance

    该方法可以在http://msdn.microsoft.com/en-us/library/system.activator.createinstance(v=vs.110).aspx见到,说明就比较明确了:

    用最匹配的构造函数创建一个类型的实例(Creates an instance of the specified type using the constructor that best matches the specified parameters)。

    写法也很爽:

    class MyClass<T>
    {
        public MyClass(string request)
        {
            this.MyObject = (T)Activator.CreateInstance(typeof(T), request);
        }
    
        T MyObject { get; set; }
    }

    这种方法做得到,也很简短,也不用多做接口和基类。

    缺点就是没有约束,没办法保证T能有带指定数量和类型参数的构造函数,或者是否有构造函数。

    如果T不符合设计需求的话会报相应的异常

     

     

    原来泛型的类型参数是这么设计的

    至此,便可以知道,C#的泛型里,类型参数是一种“非类”的存在,类型参数的约束(Constraints on Type Parameters)仅仅是用来描述具体的类在实例化或者继承时所需要达到的条件。而在泛型内部,类型参数仅仅是一种“特别的存在”,它用来描述类,但却无法用作类。

     

     

    那么,类型参数可以有......参考本文题目......

    首先,其实这个问题本身就是泛型的类型参数能否有带参数的实例化方式,比如 T myObject = new T("Hello World!“) 。

    然后,由于类型参数是用“约束”的方式来进行实例类的特点的描述的,所以,问题才变成了泛型的类型参数能否有带参数的构造函数的约束方式,比如 where T : new(string) 。

    要做假设的话,起始就是个证伪的问题,要证明它存在是否会造成什么原则问题。

    首先能对比的就是泛型的类型参数已经有了不带参数的构造函数的约束方式了,那么泛型的类型参数就算有带了参数的构造函数的约束方式又如何?至少,泛型的类型参数已经有了不带参数的构造函数的约束方式证明了泛型的类型参数有构造函数的约束方式并不会造成什么问题而且技术上是可以实现的。(......)

    在我们实例化一个新对象的时候通常会用两种初始化方式:

    • 利用构造函数传参
    • 实例化后赋值

    大部分情况下两种方式产生的结果是差不多的,这种大部分情况是指一般所涉及到的属性或参数都是公开的(public),本来就是开放读写的,所以内部写和外部写都差不多。

    但遇到一些情况,比如一些业务约束,需要对参数进行处理或者利用参数进行操作,最终操作结果是私密的(private),那么就会偏向于选用构造函数传参。或者会使用一个特殊的方法,由该方法在类实例化之后再把需要的数据带进来进行操作,这么做些许有失“一气呵成”的爽快。

    利用构造函数传参并不是什么容易替代的方式,因为它在绝大部分属于它的场景里都是最优的解决方案。有时候,初始化一个对象到使用,一气呵成是最好的,因为这个事务本身就有很强的原子性。一个对象的两种初始化方式造成了双入口的麻烦,作为该类的使用者,有时候你会模糊,两种方式所产生的结果你无法准确地把握;对于开发者,两种实现方式供的出现在规范上也要求要么二选一,要么保证两者一致。当类变得相对复杂的时候,事情就没那么简单了。

    所以,我们确实会需要泛型的类型参数有带了参数的构造函数的约束方式的一些场景。它虽然不是必要的,但是绝对是一种需要,就像get/set访问器那样。

     

     

    补充地说,其实更大的命题是类型参数是否可以当作类使用

    假设它可以由带参数的构造函数约束了,那么可不可以直接如约束那样当作类来使用呢?比如调用静态方法?在泛型中创建继承于该类型参数的类?

    如此种种算来发现每一种都有可能是特例,而不是一个简单的实现即可解决的。

    比如调用静态方法来说,T.Hello()所涉及的就是执行的时候T能明确是哪个类;而在泛型类中创建继承于该类型参数的类就会变得复杂。

    单单想想调用那个类的方法:MyClass<T>.MySubClass,这里的语法就有点“不一般”了,未必是一个“仅仅是泛型本身的问题”。

    逼格高一点地说,越来越多的功能对C#或者任何一门语言来说是一条正确的道路吗?

     

     

    关于题目

    如果你有不满,可以提供合适的标题,禁止以任何方式攻击作者!

     

     

     

     

    转载于:https://www.cnblogs.com/indream/p/3667279.html

    展开全文
  • java中一个类中可以定义多个无参构造函数,理由是:可以再定义局部类的空参构造方法 package demo01; public class Demo01 { public static void main(String[] args) { Outer outer=new Outer(); Outer....

    java中一个类中可以定义多个无参构造函数,理由是:可以再定义局部类的空参构造方法

    package demo01;
    
    public class Demo01 {
    
    	public static void main(String[] args) {    
    		Outer outer=new Outer();
    		Outer.Inner inner = outer.new Inner(); // 创建内部类对象
    		inner.show1(); // 测试在成员内部类中访问外部类成员变量和方法
    		outer.test2(); // 测试在外部类中访问内部类成员变量和方法
    	}
    }
    
    //定义外部类Outer
    class Outer {
    	Outer(){
    		System.out.println("调用了外部类的无参构造函数");
    	}
    	int m = 0; // 定义外部类的成员变量
    	// 定义外部类成员方法
    	void test1() {
    		System.out.println("外部类成员方法");
    	}
    	// 定义成员内部类Inner
    	class Inner {
    		Inner(){
    			System.out.println("调用了内部类的无参构造函数");
    		}
    		int n = 1;
    		// 1、定义内部类方法,访问外部类成员变量和方法
    		void show1() {
    			System.out.println("外部类成员变量m="+m);
    			test1();
    		}
    		void show2(){
    			System.out.println("内部类成员方法");
    		}
    	}
    	// 2、定义外部类方法,访问内部类变量和方法
    	void test2() {
    		Inner inner = new Inner();
    		System.out.println("内部类成员变量n="+inner.n);
    		inner.show2();
    	}
    }
    
    
    展开全文
  • 在一个类中可以定义多个构造函数版本,即构造函数允许被重载,只要每个构造函数的形参列表是唯一的。一个类的构造函数数量是没有限制的。一般地,不同的构造函数允许建立对象时用不同的方式来初始化数据成员。 构造...
  • 外部可以调用内部类方法吗?

    千次阅读 2021-02-12 14:20:49
    外部可以通过创建外部对象来创建内部对象再调用内部方法class Outer{ // 定义外部类private String info = "hello world" ; // 定义外部类的私有属性class Inner{ // 定义内部类public void print(){ // 定义内部...
  • 不一定 类体外定义的是一种引用数据类型, add 是成员变量并且还是一个实例变量,所以add也是一个引用 2.程序在什么情况下会出现空指针异常呢? 空引用 访问 对象相关的数据时,会出现空指针异常 垃圾回收器主要针对堆...
  • 2、一个类中可以有多个构造函数,构造函数之间构成函数重载的关系 3、通常如果在定义类的时候,如果没有主动声明任何一个构造函数,系统会自动生成一个默认构造函数,默认构造函数就是不带任何参数构造函数。其它...
  • 什么是构造函数及定义

    千次阅读 多人点赞 2021-03-07 20:47:43
    什么是构造函数 建立一个对象时,通常最需要立即做的工作是初始化对象,如对数据成员赋初值 构造函数就是用来在创造对象时初始化对象,为对象数据成员赋初始值
  • 我们大家都学习了 Huffman 算法,给出每一个点的权值,它可以求出一个具有最小加权外部路径的二叉树,也就是使造价 (树枝长度为根结点到叶结点边数) 最小的二叉树。现在由你来完成这项工作。 思路 方法一 不构造...
  • 私有成员变量的概念,在脑海中的现象是,以private关键字声明,是类的实现部分,不对外公开,不能在对象外部访问对象的私有成员变量. 然而,在实现拷贝构造函数和赋值符函数时,在函数里利用对象直接访问了私有...
  • 什么是外部排序?

    千次阅读 2021-08-18 14:36:59
    外部排序外部排序的基本概念外部排序的方法后续 外部排序的基本概念 在内存中进行的排序是内部排序,而在许多应用中,经常需要对大文件进行排序,因为文件中的记录很多、信息量庞大,无法将整个文件复制进内存中进行...
  • 构造函数就是用来用来在创建对象时初始化对象, 为对象数据成员赋初始值 -类的数据成员是不能在类定义时初始化的, 例如: class Point //Point类 { int x=0, y=0; //错误, 不能在类定义中对数...
  • 注意:在内部类构造的时候,会将外部类的引用传递进来,并且作为内部类的一个属性,所以内部类会持有一个其外部类的引用。当内部类调用外部类的私有属性时,其真正的执行是调用了编译器生成的属性的静态方法(即acess...
  • 构造上讲,相关区域位于阿拉伯板块的外部平台(不稳定的架子)内。 在结构上,除了电子战趋势的两个主要正常断层以及强烈的节理和构造外; 该地区没有其他功能。 强烈的喀斯特地貌,界线的存在和新构造活动已经...
  • 则需父类外部实例来初始化如果定义在非静态作用域内,会引用外部类实例只能捕获外部作用域内的final变量创建时只有单一方法的接口可以用Lambda转换a.匿名内部类的名字表面上是没有引用名的,但其实是有用于定位的...
  • 哈夫曼树也叫做最优二叉树。。如果扩充二叉树的外部节点都带有一定...(摘抄自算法与数据结构课本)。 而关于哈夫曼树的应用,有哈夫曼编码与二路归并排序。。哈夫曼编码就是比如说要用二进制编译一段文字编码。。所以就
  • 1.标准构造函数,可选参数,默认参数,初始化列表,命名构造函数,工厂构造函数,命名工厂构造函数,get,set,静态方法,抽象方法,抽象类 //所有的类都继承自Object class Person { String name; int age; Person(this....
  • 在java怎么调用代参的构造函数

    千次阅读 2021-03-08 08:14:41
    构造函数 是一种特殊的方法 主要用来在创建对象时初始化对象 即为对象成员变量赋初始值总与new运算符一起使用在创建对象的语句中 特别的一个类可以有多个构造函数 可根据其参数个数的不同或参数类型的不同来区分它们...
  • 构造方法与参数传递

    万次阅读 2017-02-04 18:53:06
    构造方法*java中没有构造函数的概念 构造方法是创建对象时调用的方法,不要理解为构造方法就是创建对象的方法,因为构造方法主要是用来加载和初始化类的一些资源,创建一个对象并不完全靠 构造方法完成,构造方法...
  • C++类的构造函数可以私有吗?

    千次阅读 2019-11-19 11:18:14
    我们知道,当我们在程序中声明一个对象时,编译器为调用构造函数(如果有的话),而这个调用将通常是外部的,也就是说它不属于class对象本身的调用,假如构造函数是私有的,由于在class外部不允许访问私有成员,所以这...
  • 导入 昨天简单介绍了怎么创建类 那么我们在java的程序中为什么需要创建对象呢?创建对象的作用是什么呢? 在此之前,我们需要了解一个东西,java中如果...1.构造方法 其中,实例方法这一块我们有约定,可以分成构...
  • ( )【判断题】在成员方法中可以使用“this([参数1,参数2...])”来调用其它的构造方法。( )【单选题】当一个类中成员变量和局部变量重名时,可以使用哪个关键字进行区分( )【判断题】static关键字可以修饰成员变量,也...
  • Java构造器(构造方法)详解

    千次阅读 多人点赞 2021-09-11 21:47:58
    [修饰符,比如public] 类名 (参数列表,可以没有参数){ //这里不能有return} 文章目录Java构造器(构造方法)详解Java构造器怎么定义构造构造器的使用构造器的继承**构造器、静态代码块、构造代码块的执行顺序,...
  • 本文要解决的场景如下:前端multipartfile 上传文件,后端接收后构造post请求,调用外部接口,传送文件流及其他参数内容包括:1.前端postman调用上传接口2.后端接收multipartfile文件3.后端用httpclien...
  • java(构造方法)

    千次阅读 2021-02-13 01:56:43
    构造方法构造方法的定义在一个类中定义的方法如果同时满足以下三个条件,该方法称为构造方法,具有如下:【1】方法与类名相同。【2】在方法名的前面没有返回值类型的声明。【3】在方法中不能使用return语句返回一个...
  • Java构造方法和子类构造方法

    千次阅读 多人点赞 2019-07-21 23:50:09
    Java构造方法 构造方法是用于初始化一个新建的对象。 普通构造方法 方法名与类名相同 无返回类型 子类不能继承父类的构造方法 不能被static、final、abstract修饰(有final和abstract修饰的是不能被子类继承的,...
  • #include &lt;iostream&gt;using namespace std;... //声明带参数构造函数  int volume(); private: int length; int width; int height;};Box::Box(int len,int w,int h){ height=h...
  • 【java基础】构造器是啥?有啥用?

    千次阅读 2019-06-08 16:08:57
    不过即使在创建对象时没有写构造器也不用担心,因为系统会默认提供一个无参数构造器。此构造器能对各种数据类型进行赋初值。 类型 初始值 数值类型 0 布尔类型 false 引用类型 null 自定义...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 391,844
精华内容 156,737
关键字:

哪些数据是外部可以构造的