Out of order chained constructors - java

public class ParentClass
{
public ParentClass(int param);
}
public class MyClass extends ParentClass
{
private int _a;
private int _b;
private int _c;
public MyClass(String input)
{
_a=CalculateA(input);
_b=CalculateB(_a);
_c=CalculateC(_a);
super(_b+_c);
}
//a expensive procedure
private int CalculateA(String text);
private int CalculateB(int a);
private int CalculateC(int a);
}
Java doesn't allow chained constructors to be anything other than the first method put in a constructor.
Chained constructors can't call nonstatic methods as arguments (which removes the possibility of using Initialsers that return the value they initialize to).
How do I achieve the above code using legal Java?

Edit Indeed Java does not allow a constructor to do any calculations before the call to a parent's class constructor, even if these involve only static methods (as your calculateX's should be) and results only assigned to variables that are private to the class (like your _a, _b and _c) or local to the constructor.
There is a way around this, however: call another constructor with the result of the calculateX call assigned to its parameter - then you can access this result throughout the other constructor.
public class MyClass extends ParentClass {
private int _a,_b,_c;
public MyClass(String input) {
this(calculateA(input));
}
private MyClass(int a) {
this(a, calculateB(a), calculateC(a));
}
private MyClass(int a, int b, int c) {
super(b + c);
this._a = a;
this._b = b;
this._c = c;
}
private static int calculateA(String text) {
try {Thread.sleep(1000);} catch (Exception e) {} // expensive ;-)
return text.length();
}
private static int calculateB(int a) { /* ... */ }
private static int calculateC(int a) { /* ... */ }
}
Edit 2 With more calculations or more intermediate results to store for later use, this approach would lead to an even longer chain of constructors consisting only of this(...)-calls. A more fancy solution with only two constructors, the public one and one private, is possible with a helper class (reasonably an inner class):
public MyClass(String input) {
this(new InitCalcResult(input));
}
private MyClass(InitCalcResult initCalcResult) {
super(initCalcResult.initB + initCalcResult.initC);
this._a = initCalcResult.initA;
this._b = initCalcResult.initB;
this._c = initCalcResult.initC;
}
private static class InitCalcResult {
private int initA, initB, initC;
InitCalcResult(String input) {
initA = calculateA(input);
initB = calculateB(initA);
initC = calculateC(initA);
}
}
(using the same private fields and static calculateX methods as above).

You can do something like this.
public abstract class ParentClass
{
public ParentClass(String input){
int a = getData(input);
/* Do what ever u need to do with a*/
};
public abstract int getData(String input);
}
public class MyClass extends ParentClass
{
private int _a;
private int _b;
private int _c;
public MyClass(String input)
{
super(input);
}
public int getData(String input){
_a=CalculateA(input);
_b=CalculateB(_a);
_c=CalculateC(_a);
return _b+_c;
}
//a expensive procedure
private int CalculateA(String text){/* return int */};
private int CalculateB(int a){/* return int */};
private int CalculateC(int a){/* return int */};
}
Since getData is abstract, the base class function will get called. And the super class will get the required data.

Related

How to make a method with a return statement that is inside an abstract class which implements an interface get inherited by a subclass?

I will post the part of the code that I have trouble with. I scoured the internet for hours and cannot find a solution to how to properly solve this problem with a method that has a return and isn't just a sentence. I would seriously appreciate any help that I can get! Essentially what I need is for my subclass to inherit the same method in its abstract father without any changes, so that I can apply that in my main code.
public class Main {
interface Dodela
{
public int PovecajKS();
public int SmanjiS();
}
public static abstract class Ekspanzija implements Dodela
{
final public int PovecajKS(int a, int b)
{
a = a + b;
return a;
}
final public int SmanjiS(int a, int b)
{
a = a - b;
return a;
}
}
public static class EkspanzijaP extends Ekspanzija implements Dodela
{
public int PovecajKS()
{
}
public int SmanjiS() {
int a = 0, b = 0;
a = a - b;
return a;
}
}
It already inherits all methods of its father, to use the method inside the subclass, it can be called like this
super.yourFunctionName()

How to reintegrate anonymous classes into Java code produced by the ECD decompiler?

I have a jar for school that is supposed to be decompiled, modifed, and reevaluated. I decompiled all of the class files using the ECD plugin for Eclipse, but I think I have a few anonymous classes that were extracted and need to be merged back into another class. I have a class P, and then five more classes named P$1, P$2, ..., P$5.
Here's the problem parts of P:
public class P {
private ArrayList<Family> group;
private int marker;
private Integer primaryElement;
Comparator<Family> c;
public P(ArrayList<Family> g, Integer i, Comparator<Family> c) {
this.marker = -1;
this.group = new ArrayList(g);
this.primaryElement = i;
this.c = c;
}
/* Some unrelated methods */
public String printHeader() {
return this.print(new 1(this));
}
public String printRow(Integer i) {
return this.print(new 2(this, i));
}
public String printPad() {
return this.print(new 3(this));
}
public Object printCost() {
return this.print(new 4(this));
}
public String printLine() {
return this.print(new 5(this));
}
Here is P$1. The others are very similar.
final class P$1 implements PrintCommand {
P$1(P arg0) {
this.this$0 = arg0;
}
public String print(Family f) {
return String.format("%3d", new Object[]{Integer.valueOf(f.getId())});
}
}
In case you're wondering, PrintCommand is a super simple interface:
public interface PrintCommand {
String print(Family arg0);
}
How can I get P$1 merged back into P? Also, what does this.this$0 mean in P$1?
In an anonymous class you can reference the this from the enclosing class with P.this. To do that, the java compiler will create a constructor, which will set a field named this$0 to the reference passed to the constructor.
The original code probably looked like this:
public String printHeader() {
return this.print(new PrintCommand() {
public String print(Family f) {
return String.format(%3d", f.getId());
}
);
}
There are other things the compiler does, for example adding accessor methods for private methods/fields from the enclosing class that are accessed in the inner class. Or passing the value of (effectively) final variables used in the inner class to the constructor.
From the perspective of the Java Runtime, there is no anonymous inner class, only named classes.

When creating a builder with a superclass, parent cannot return instance of child class [duplicate]

This question already has answers here:
Subclassing a Java Builder class
(10 answers)
Closed 6 years ago.
If I am using the builder pattern to configure new objects I may have two classes like Game and HockeyGame (shown below). When I want to create a new HockeyGame, I get it's builder and start calling methods to configure the object as needed.
The problem I am running into is shown in the main function. Once I call one method from the super class it returns as an intance of Game.Builder, and I can no longer call any method from the child class.
What is the best way to deal with this?
Main.java
class Main {
public static void main(String[] args){
HockeyGame hg = new HockeyGame.Builder()
.setScore(5)
.setTimeLimit(3600)
//--------------------------------------------------------------------
.setIceTemperature(-5) // Error! Cannot call setIceTempurature() on
// an instance of Game.Builder
//--------------------------------------------------------------------
.build();
}
}
Game.java
public class Game{
int score;
int timeLimit;
public Game(int score, int timeLimit) {
this.score = score;
this.timeLimit = timeLimit;
}
public static class Builder {
int score;
int timeLimit;
public Builder setScore(int score) {
this.score = score;
return this;
}
public Builder setTimeLimit(int timeLimit) {
this.timeLimit = timeLimit;
return this;
}
public Game build() {
return new Game(score, timeLimit);
}
}
}
HockeyGame.java
public class HockeyGame extends Game {
float iceTemperature;
public HockeyGame(int score, int timeLimit, float iceTemperature) {
super(score, timeLimit);
this.iceTemperature = iceTemperature;
}
public static class Builder extends Game.Builder {
float iceTemperature;
public HockeyGame.Buidler setIceTemperature(float iceTemperature) {
this.iceTemperature = iceTemperature;
return this;
}
public HockeyGame build(){
return new HockeyGame(score, timeLimit, iceTemperature);
}
}
}
Thanks.
You need to use the getThis() trick that is prevalent in much fluent API code.
First you need to make your Game.Builder generic in itself:
public static class Builder<B extends Builder<B>>
Then you add a getThis() method:
public B getThis() {
return (B) this;
}
Now you change your setters to return a B and return getThis() rather than this:
public B setTimeLimit(int timeLimit) {
//...
return getThis();
}
Your extension class also needs to be generic, in itself:
public static class Builder<B extends Builder<B>> extends Game.Builder<B>
Now you can use the code, and it will "remember" the intended type:
HockeyGame hockeyGame = new HockeyGame.Builder<>().setScore(10)
.setTimeLimit(20)
.setIceTemperature(-1)
.build();
This final code looks something like:
public class Game {
private final int score;
private final int timeLimit;
private Game(final Builder<?> builder) {
this.score = builder.score;
this.timeLimit = builder.timeLimit;
}
public static class Builder<B extends Builder<B>> {
private int score;
private int timeLimit;
public B setScore(int score) {
this.score = score;
return getThis();
}
public B setTimeLimit(int timeLimit) {
this.timeLimit = timeLimit;
return getThis();
}
protected B getThis() {
return (B) this;
}
public Game build() {
return new Game(this);
}
}
}
public class HockeyGame extends Game {
private final float iceTemperature;
private HockeyGame(final Builder<?> builder) {
super(builder);
this.iceTemperature = builder.iceTemperature;
}
public static class Builder<B extends Builder<B>> extends Game.Builder<B> {
private float iceTemperature;
public B setIceTemperature(float iceTemperature) {
this.iceTemperature = iceTemperature;
return getThis();
}
#Override
public HockeyGame build() {
return new HockeyGame(this);
}
}
}
N.B: I have made the fields private final and also the main type constructors - this forces people to use the Builder. Also, the constructor can take a Builder<?> and copy the variable from there - this tidies the code a little.
The actual hack is, as you may have noticed, here:
public B getThis() {
return (B) this;
}
Here, we force a cast of the Builder to its generic type - this allows us to change the return type of the method dependant upon the specific instance being used. The issue is, if you declare a new Builder something like the following:
public static class FootballGame extends Game {
private FootballGame(final Builder<?> builder) {
super(builder);
}
public static class Builder<B extends HockeyGame.Builder<B>> extends Game.Builder<B> {
float iceTemperature;
#Override
public FootballGame build() {
return new FootballGame(this);
}
}
}
This this will blow up at runtime with a ClassCastException. But the setter method will return a HockeyGame.Builder rather than FootballGame.Builder so the issue should be obvious.
Try something like this
You explicitely cast it back to a HockeyGame.Builder object and work with its own method(s) on it.
The problem you had is that setTimeLimit returns a Builder object (mother class) and so you can not use the child methods on it.
HockeyGame hg = ((HockeyGame.Builder)(new HockeyGame.Builder().setScore(5)
.setTimeLimit(3600)))
.setIceTemperature(-5)
.build();
Also, setIceTemparature should return a HockeyGame.Builder object to be able to build on it.
public Builder setIceTemperature(float iceTemperature) {
this.iceTemperature = iceTemperature;
return this;
}

How does a static method use a comparator?

I have a static method which needs to invoke the SportsMenComparator. But this, as we all know is not allowed. How does a static function use a comparator subclass ? Although I have workarounds, I am looking for best practices for this particular problem.
final class SportsMan {
private final String name;
private final int rank;
private final String sport;
public SportsMan (String name, int rank, String sport) {
this.name = name;
this.rank = rank;
this.sport = sport;
}
public String getName() {
return name;
}
public int getRank() {
return rank;
}
public String getSport() {
return sport;
}
}
final class Sport {
private final String sport;
private final int numberOfPlayers;
public Sport(String sport, int numberOfPlayers) {
this.sport = sport;
this.numberOfPlayers = numberOfPlayers;
}
public String getSport() {
return sport;
}
public int getNumberOfPlayers() {
return numberOfPlayers;
}
}
public final class Joins {
private Joins () {}
public class SportsMenComparator implements Comparator<SportsMan> {
#Override
public int compare(SportsMan s1, SportsMan s2) {
return s1.getSport().compareTo(s2.getSport());
}
}
public static void innerJoinSort(List<SportsMan> sportsMans, List<Sport> sportList) {
Collections.sort(sportsMans, new SportsMenComparator());
}
}
Eclipse results in the following message: No enclosing instance of type Joins is accessible where Joins is name of the enclosing class.
But this, as we all know is not allowed. How does a static function use a comparator subclass ?
You cannot use a non static reference,still you are allowed to create a new object and use it. So since you are creating a new SportsMenComparator object and passing, no issues.
For example:
public static void main(String[] args) {
List<String> s =new ArrayList<String>();
s.add(""); // allowed
}
But
List<String> s =new ArrayList<String>();
public static void main(String[] args) {
System.out.println();
s.add(""); // Error: Cannot make a static reference to the non-static field s
}
Edit:
Since you defined the comparator class inside the Joins , you need the Joins object to access the comparation inside it
Collections.sort(sportsMans, new Joins().new SportsMenComparator());
For using a Comparator, there is no difference between using it from a static- or non-static method. In either case an instance of the Comparator has to be used.
The Garbage Collector of modern JVMs is very efficient at handling short-lived objects. Therefore the penalty to be paid for using a fresh instance (via new) every time is usually no issue. However, if you don't want to use a fresh instance every time, I think the best option would be to add a static field to your SportsMenComparator, containing a singleton instance of the comparator:
public class SportsMenComparator implements Comparator<SportsMan> {
public static final SportsMenComparator instance=new SportsMenComparator();
#Override
public int compare(SportsMan s1, SportsMan s2) {
return s1.getSport().compareTo(s2.getSport());
}
}
public static void innerJoinSort(List<SportsMan> sportsMans, List<Sport> sportList) {
Collections.sort(sportsMans, SportsMenComparator.instance);
}
The problem is that you try to access an instance element (in this case it is a class, indeed the same as with a filed or method) within a static method, which is not associated with an instance. SURESH ATTA's answer is right, but you can also make your SportsMenComparator class static and it will work. I do not sse any reason to associate your comparator with an instance of the Joins class.
One can use something like this---
public static boolean someMethod(MyObject obj1, MyObject obj2){
return obj1.compare(obj2);
}
Why you cant include parameter to the function.
public static void innerJoinSort(List<SportsMan> sportsMans, List<Sport> sportList, Comparator comparator) {
Collections.sort(sportsMans, comparator);
}

Java - Add Parameter to Class

I am trying to add a parameter at the declaration of a class.
Here is the declaration:
public static class TCP_Ping implements Runnable {
public void run() {
}
}
This is what I am trying to do:
public static class TCP_Ping(int a, String b) implements Runnable {
public void run() {
}
}
(which doesn't work)
Any suggestions? thanks!
You probably want to declare fields, and get the values of the parameters in the constructor, and save the parameters to the fields:
public static class TCP_Ping implements Runnable {
// these are the fields:
private final int a;
private final String b;
// this is the constructor, that takes parameters
public TCP_Ping(final int a, final String b) {
// here you save the parameters to the fields
this.a = a;
this.b = b;
}
// and here (or in any other method you create) you can use the fields:
#Override public void run() {
System.out.println("a: " + a);
System.out.println("b: " + b);
}
}
Then you can create an instance of your class like this:
TCP_Ping ping = new TCP_Ping(5, "www.google.com");
Use Scala! This is supported nicely.
class TCP_Ping(a: Int, b: String) extends Runnable {
...
You cannot declare concrete parameters on the class heading (there are such things as type parameters, but that's not what you need as it appears). You should declare your parameters in the class constructor then:
private int a;
private String b;
public TCP_Ping(int a, String b) {
this.a = a;
this.b = b;
}

Categories