|
Java rant. Or is there a pretty workaround? |
type568
Member #8,381
March 2007
|
public NewCandle(String line){ Pattern p = Pattern.compile(P_PRICE+" "+P_PRICE+" "+P_PRICE+" "+P_PRICE+" "+P_CHANGE+" "+P_UNS+" "+P_UNS+"."+P_UNS+"."+P_UNS); Matcher m=p.matcher(line); this=new NewCandle(null); if(m.find()) this(m.group(1),m.group(2),m.group(3),m.group(4),m.group(5),m.group(6),m.group(7),m.group(8),m.group(9)); else{ GA.GA.reportError("DataManager.NewCandle.NewCandle: Failed to parse line."); this(null,null,null,null,null,null,null,null,null); } }
The other constructor is capable of taking nine Strings representing these groups.. error: call to this must be first statement in constructor
Which actually doesn't surprise me, I remember it from the old good days during which I studying on the university not even knowing what a OHLC* is. But Jesus, is there no work around better than copy-pasting my code? Only thing I can think about is a static Method which is gonna return that NewCandle, which well.. Implies different functionality a little. *- Open, High, Low, Close. What represents a single candle on a chart of more or less any financial instrument tradable on an exchange.
|
torhu
Member #2,727
September 2002
|
Which line is the problem? |
type568
Member #8,381
March 2007
|
Two errors, both calls to this(..).
|
torhu
Member #2,727
September 2002
|
Use an array or an ArrayList? APPEND: Uh, what you are doing doesn't look like Java to me. Why are you assigning to this? |
Edgar Reynaldo
Major Reynaldo
May 2007
|
My Java's a little rusty, but can you do this? if (m.find()) { this = new NewCandle(m.group(1)...); } else { this = new NewCandle(null,...); }
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
type568
Member #8,381
March 2007
|
this() is a call to a constructor. That is, my constructor taking a single String, is parsing this string to nine other strings, and intends to pass them on to another constructor. A larger chunk of the code looks like this: 1public NewCandle(BigDecimal open,BigDecimal high,BigDecimal low, BigDecimal close,BigDecimal change,BigDecimal volume,int day,int month,int year){
2 _data=new BigDecimal[7];
3 _data[TYPE.CLOSE.ordinal()]=open;
4 _data[TYPE.OPEN.ordinal()]=high;
5 _data[TYPE.HIGH.ordinal()]=low;
6 _data[TYPE.LOW.ordinal()]=close;
7 _data[TYPE.CHANGE.ordinal()]=change;
8 _data[TYPE.VOLUME.ordinal()]=volume;
9
10 DATE= new MyDate(day,month,year);
11 }
12
13 public NewCandle(float open,float high,float low,float close,float change,long volume,int day,int month,int year){
14 this(new BigDecimal(open),new BigDecimal(high),new BigDecimal(low),new BigDecimal(close),new BigDecimal(change),new BigDecimal(volume),day,month,year);
15 }
16
17 public NewCandle(String open,String high,String low,String close,String change,String volume,String day,String month,String year){
18 this(Float.parseFloat(open),Float.parseFloat(high),Float.parseFloat(low),Float.parseFloat(close),Float.parseFloat(change),Long.parseLong(volume),Integer.parseInt(day),Integer.parseInt(month),Integer.parseInt(year));
19 }
20
21 public NewCandle(String line){
22 Pattern p = Pattern.compile(P_PRICE+" "+P_PRICE+" "+P_PRICE+" "+P_PRICE+" "+P_CHANGE+" "+P_UNS+" "+P_UNS+"."+P_UNS+"."+P_UNS);
23 Matcher m=p.matcher(line);
24 this=new NewCandle(null);
25 if(m.find())
26 this(m.group(1),m.group(2),m.group(3),m.group(4),m.group(5),m.group(6),m.group(7),m.group(8),m.group(9));
27 else{
28 GA.GA.reportError("DataManager.NewCandle.NewCandle: Failed to parse line.");
29 this(null,null,null,null,null,null,null,null,null);
30 }
31 }
Nope, what Edgar suggests returns with an error saying this is final(an analogue of CONST of C , IIRC). P.S:
|
torhu
Member #2,727
September 2002
|
You can't assign to this in Java. What compiler are you running your code through? |
MiquelFire
Member #3,110
January 2003
|
I think for times like this, you would need an init function of sorts. Something like this: 1public NewCandle(BigDecimal open,BigDecimal high,BigDecimal low, BigDecimal close,BigDecimal change,BigDecimal volume,int day,int month,int year){
2 init(open,high,low,close,change,volume,day,month,year);
3 }
4
5 public NewCandle(float open,float high,float low,float close,float change,long volume,int day,int month,int year){
6 init(new BigDecimal(open),new BigDecimal(high),new BigDecimal(low),new BigDecimal(close),new BigDecimal(change),new BigDecimal(volume),day,month,year);
7 }
8
9 public NewCandle(String open,String high,String low,String close,String change,String volume,String day,String month,String year){
10 init(Float.parseFloat(open),Float.parseFloat(high),Float.parseFloat(low),Float.parseFloat(close),Float.parseFloat(change),Long.parseLong(volume),Integer.parseInt(day),Integer.parseInt(month),Integer.parseInt(year));
11 }
12
13 public NewCandle(String line){
14 Pattern p = Pattern.compile(P_PRICE+" "+P_PRICE+" "+P_PRICE+" "+P_PRICE+" "+P_CHANGE+" "+P_UNS+" "+P_UNS+"."+P_UNS+"."+P_UNS);
15 Matcher m=p.matcher(line);
16 if(m.find())
17 init(m.group(1),m.group(2),m.group(3),m.group(4),m.group(5),m.group(6),m.group(7),m.group(8),m.group(9));
18 else{
19 GA.GA.reportError("DataManager.NewCandle.NewCandle: Failed to parse line.");
20 init(null,null,null,null,null,null,null,null,null);
21 }
22 }
23
24
25private void init(BigDecimal open,BigDecimal high,BigDecimal low, BigDecimal close,BigDecimal change,BigDecimal volume,int day,int month,int year) {
26 _data=new BigDecimal[7];
27 _data[TYPE.CLOSE.ordinal()]=open;
28 _data[TYPE.OPEN.ordinal()]=high;
29 _data[TYPE.HIGH.ordinal()]=low;
30 _data[TYPE.LOW.ordinal()]=close;
31 _data[TYPE.CHANGE.ordinal()]=change;
32 _data[TYPE.VOLUME.ordinal()]=volume;
33
34 DATE= new MyDate(day,month,year);
35}
--- |
type568
Member #8,381
March 2007
|
@torhu tbh I'm clueless what's under the hood of the IDE, which is.. Oh: Product Version: NetBeans IDE 8.0.2 (Build 201411181905) Updates: NetBeans IDE is updated to version NetBeans 8.0.2 Patch 2 Java: 1.8.0_45; Java HotSpot(TM) 64-Bit Server VM 25.45-b02 Runtime: Java(TM) SE Runtime Environment 1.8.0_45-b15 System: Windows 7 version 6.1 running on amd64; Cp1251; en_US (nb) User directory: C:\Users\type568\AppData\Roaming\NetBeans\8.0.2 Cache directory: C:\Users\type568\AppData\Local\NetBeans\Cache\8.0.2 @MiquelFire Yeah well. Your approach is way better than what I thought about with making an public static creator of the class, and well.. It sure is better than copying. But still sad, my approach is the most elegant out there, and it just doesn't work cos' they said so. I suppose I'll go with Miquel's suggestion, thanks. Append: I won't be implementing it right now, but now I do wonder if the compiler gonna see I did assign values to all final fields.. It may not
|
torhu
Member #2,727
September 2002
|
You cannot assign to this. Remove that part of your code and see what happens. Also, wait until the mushrooms wear off until you do any more programming |
Edgar Reynaldo
Major Reynaldo
May 2007
|
While we're on the topic of Java, does a call to another constructor using 'this' have to be first? My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Elias
Member #358
May 2000
|
type568 said: Your approach is way better than what I thought about with making an public static creator of the class, I think that actually is close to what the true Java way would be. Just have your creator ("factory") live in a separate class. Remember, in Java, the more separate classes you can come up with to implement a task the better: class NewCandleFactory { public NewCandle makeNewCandle(String line) { Pattern p = Pattern.compile(P_PRICE+" "+P_PRICE+" "+P_PRICE+" "+P_PRICE+" "+P_CHANGE+" "+P_UNS+" "+P_UNS+"."+P_UNS+"."+P_UNS); Matcher m=p.matcher(line); if(m.find()) return new NewCandle(m.group(1),m.group(2),m.group(3),m.group(4),m.group(5),m.group(6),m.group(7),m.group(8),m.group(9)); else{ GA.GA.reportError("DataManager.NewCandle.NewCandle: Failed to parse line."); return new Newcandle(null,null,null,null,null,null,null,null,null); } } }
-- |
Edgar Reynaldo
Major Reynaldo
May 2007
|
That's basically what I suggested. Although your way is actually legal in Java. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
type568
Member #8,381
March 2007
|
Edgar Reynaldo said: While we're on the topic of Java, does a call to another constructor using 'this' have to be first? Yes, unfortunately it has to be the first line of a different overloaded constructor. Same as a call to super, if you wish to invoke the constructor of a parent class in a constructor of inheriting class. Now if you can invoke both(since one will be a second line) I'm not sure, I think you can as long as only line before this() you have is a super(). @Elias I'll add a reply or edit this message after implementing it. Most likely will be tonight (@ GMT +3).
|
bamccaig
Member #7,536
July 2006
|
type568 said: This would make no sense. If it was possible it would be infinitely recursive and overflow the stack! Not to mention, it wouldn't make sense for this to change mid-constructor. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
type568
Member #8,381
March 2007
|
@bammcaig Append: ah, yeah.. Didn't change it back. Was just to make sure such an assignment isn't possibre. The error there is that can't assign to a final value, which was what I wanted to check for which I needed some existing constructor with few arguments. Append1: public static NewCandle candleFromString(String line){ Pattern p = Pattern.compile(P_PRICE+" "+P_PRICE+" "+P_PRICE+" "+P_PRICE+" "+P_CHANGE+" "+P_UNS+" "+P_UNS+"."+P_UNS+"."+P_UNS); Matcher m=p.matcher(line); if(m.find()) return new NewCandle(m.group(1),m.group(2),m.group(3),m.group(4),m.group(5),m.group(6),m.group(7),m.group(8),m.group(9)); else{ GA.GA.reportError("DataManager.NewCandle.NewCandle: Failed to parse line."); return new NewCandle(null,null,null,null,null,null,null,null,null); } } Generally instead of overloading the constructor, I made a passive method which returns a NewCandle by actually creating it with data parsed from the given line.
|
|