In Java you are allowed to do this:
class A {
private final int x;
public A() {
x = 5;
}
}
In Dart, I tried:
class A {
final int x;
A() {
this.x = 5;
}
}
I get two compilation errors:
The final variable 'x' must be initialized.
and
'x' can't be used as a setter because its final.
Is there a way to set final properties in the constructor in Dart?
You cannot instantiate final fields in the constructor body. There is a special syntax for that:
class Point {
final num x;
final num y;
final num distanceFromOrigin;
// Old syntax
// Point(x, y) :
// x = x,
// y = y,
// distanceFromOrigin = sqrt(pow(x, 2) + pow(y, 2));
// New syntax
Point(this.x, this.y) :
distanceFromOrigin = sqrt(pow(x, 2) + pow(y, 2));
}
You can make it even shorter with this. syntax in the constructor (described in https://www.dartlang.org/guides/language/language-tour#constructors):
class Point {
final num x;
final num y;
final num distanceFromOrigin;
Point(this.x, this.y)
: distanceFromOrigin = sqrt(pow(x, 2) + pow(y, 2));
}
If you have some more complicated initialization you should use factory constructor, and the code become:
class Point {
final num x;
final num y;
final num distanceFromOrigin;
Point._(this.x, this.y, this.distanceFromOrigin);
factory Point(num x, num y) {
num distance = distanceFromOrigin = sqrt(pow(x, 2) + pow(y, 2));
return new Point._(x, y, distance);
}
}
Here is a simplified summary of the ways to initialize a final class variable.
class MyClass {
final int x; // <-- initialize this
}
Initializer value
class MyClass {
final int x = 'hello'.length;
}
You'd only use final if the initialization could only be done at runtime. Otherwise, static const is better:
class MyClass {
static const int x = 0;
}
Initializer formal
class MyClass {
MyClass(this.x);
final int x;
}
This is the most common approach.
Initializer list
class MyClass {
MyClass(int x)
: _x = x;
final int _x;
}
This is useful when you want to keep a field private.
Default parameter value
You can surround the parameter with square brackets ([]) for an unnamed parameter or curly braces ({}) for a named parameter and then give it a default value.
class MyClass {
MyClass({this.x = 0});
final int x;
}
This is useful if you want to make the parameter optional.
You could accomplish the same thing with an initializer list as well:
class MyClass {
MyClass({int? x})
: _x = x ?? 0;
final int _x;
}
Late initialization
class MyClass {
MyClass(String? a) {
x = a?.length ?? 0;
}
late final int x;
}
This is useful if you need to do more complex initialization than is allowed in the initializer list. For example, I've done this when initializing a gesture recognizer in Flutter.
Lazy initialization
Another advantage of using late is that it doesn't initialize a value until you access the value.
class MyClass {
late final int x = _doHeavyTask();
int _doHeavyTask() {
var sum = 0;
for (var i = 0; i < 100000000; i++) {
sum += 1;
}
return sum;
}
}
This is useful if you have a heavy calculation that you only want call if you absolutely need it.
This doesn't initialize x:
final myClass = MyClass();
But this does initialize x:
final myClass = MyClass();
final value = myClass.x;
I've had a similar problem: I was trying to initialise a final field from the constructor, while simultaneously calling a super constructor. You could think of the following example
class Point2d {
final int x;
final int y;
Point2d.fromCoordinates(Coordinates coordinates)
: this.x = coordinates.x,
this.y = coordinates.y;
}
class Point3d extends Point2d {
final int z;
Point3d.fromCoordinates(Coordinates coordinates)
:this.z = coordinates.z,
super.fromCoordinates(coordinates);
}
/// Demo class, to simulate constructing an object
/// from another object.
class Coordinates {
final int x;
final int y;
final int z;
}
Well apparently this works. You can initialise your final fields by using the above syntax (check Point3d's constructor) and it works just fine!
Run a small program like this to check:
void main() {
var coordinates = Coordinates(1, 2, 3);
var point3d = Point3d.fromCoordinates(coordinates);
print("x: ${point3d.x}, y: ${point3d.y}, z: ${point3d.z}");
}
It should prin x: 1, y: 2, z: 3
I've come to a dilemma here where I wanted to initialize a final List with no items, and a Stream to be defined inside the constructor (like in this case distanceFromOrigin).
I couldn't do that with any of the answers below, but I mixed them both and it worked.
Example:
class MyBloc {
final BehaviorSubject<List<String>> itemsStream;
final List<String> items = [];
MyBloc() : this.itemsStream = BehaviorSubject<List<String>>.seeded([]) {
items.addAll(List.generate(20, (index) => "Hola! I'm number $index"));
itemsStream.add(items);
}
}
class A{
final int x;
A(this.x){
}
}
Related
This question already has answers here:
Serialize and Deserialize Json and Json Array in Unity
(9 answers)
Closed 3 years ago.
I'm trying to get all my lines render positions and add it to a list of vector3 then covert it to Json, so I can save it in the firebase. I'm using JsonUtility, but the problem is my jsondata is always empty even the list of vecor3 is not.
This is my code then I'm using :
public class Path : MonoBehaviour
{
[SerializeField] private List<Transform> checkpoints = new List<Transform>();
private LineRenderer linerenderer;
public Material TheLineMateriel;
public static bool _ispressed = false;
private string DATA_URL = "https://kataraproject-a233a.firebaseio.com/";
private DatabaseReference reference;
public string hello = "khraaa" ;
// Start is called before the first frame update
void Start()
{
FirebaseApp.DefaultInstance.SetEditorDatabaseUrl(DATA_URL);
reference = FirebaseDatabase.DefaultInstance.RootReference;
GameObject lineObject = new GameObject();
this.linerenderer = lineObject.AddComponent<LineRenderer>();
this.linerenderer.startWidth = 0.05f;
this.linerenderer.endWidth = 0.05f;
this.linerenderer.positionCount = checkpoints.Count;
this.linerenderer.material = TheLineMateriel;
}
// Update is called once per frame
void Update()
{
this.DrawLine();
}
private void DrawLine()
{
Vector3[] checkpointsArray = new Vector3[this.checkpoints.Count];
for (int i = 0; i < this.checkpoints.Count; i++) {
Vector3 checkpointPos = this.checkpoints[i].position;
checkpointsArray[i] = new Vector3(checkpointPos.x, checkpointPos.y, 0f);
}
Vector3[] newPos = new Vector3[linerenderer.positionCount];
this.linerenderer.SetPositions(checkpointsArray);
linerenderer.GetPositions(newPos);
//for (int i = 0; i < linerenderer.positionCount ; i++)
//{
// newPos[i] = i;
//}
if ( _ispressed == true)
{
string jsonData = JsonUtility.ToJson(checkpointsArray);
//reference.Child("Position" + Random.Range(0,1000000)).SetRawJsonValueAsync(jsonData);
Debug.Log(jsonData);
_ispressed = false;
}
}
public void Save ()
{
_ispressed = true;
}
}
can someone help me please?
You could create a simple class to handle serialization of Unity types like such :
[Serializable]
public class SerializedVector3
{
public float x;
public float y;
public float z;
public SerializedVector3(float x, float y, float z)
{
this.x = x;
this.y = y;
this.z = z;
}
public SerializedVector3(Vector3 vector3)
{
x = vector3.x;
y = vector3.y;
z = vector3.z;
}
}
public static class Vector3Extensions
{
public static Vector3 ToVector3(this SerializedVector3 serializedVector3)
{
return new Vector3(serializedVector3.x, serializedVector3.y, serializedVector3.z);
}
public static SerializedVector3 FromVector3(this Vector3 vector3)
{
return new SerializedVector3(vector3);
}
}
Uploaded screenshot of errors
This is an example to show a basic ArithmeticException is giving me error in netbeans. Any ideas.
public class Exception {
public static void main (String[] args){
try
{
double x = 0;
double y = 19000;
double z;
double practice()
{
double z = 4000;
return y - z;
}
public double practiceAgain()
{
double f = (9 + z);
return f/x;
}
}
catch (ArithmeticExecption t){
System.out.println(t);
}
}
As the error states:
Uncompilable source code – illegal start of expression at Exception:main(Exception.java:13)
Your source code is invalid out of multiple reasons:
Inside a method there is no such thing as a scope (i.e. public, protected, or private) – this is mentioned in your error message: line 13 in your main method.
Inside a method you cannot declare another method like this (i.e. on lines 18 and 24)
You have basically two ways to make the posted code compilable:
Either move the contents out of the main method:
public class Exception {
double x = 0;
double y = 19000;
double z;
public static void main (String[] args) {
try {
practice();
practiceAgain();
} catch (ArithmeticExecption t){
t.printStackTrace();
}
}
double practice() {
z = 4000;
return y - z;
}
public double practiceAgain() {
double f = (9 + z);
return f/x;
}
}
Or do your processing directly in the main method:
public class Exception {
public static void main (String[] args) {
try {
double x = 0;
double y = 19000;
double z = 4000;
double practice = y - z;
double f = (9 + z);
double practiceAgain = f/x;
} catch (ArithmeticExecption t){
t.printStackTrace();
}
}
}
I'm playing with processing from some days, but I encountered an error that i didn't understand. I declared the class and the constructor with the proper arguments, maybe you can help me. This is the code:
Cell[][] grid;
int rnc = 5;
int side = 5;
void setup(){
size(rnc*side,rnc*side);
grid = new Cell[rnc][rnc];
for(int i = 0; i < rnc; i++){
for(int j = 0; j < rnc; j++){
grid[i][j] = new Cell(i,j);
rect(grid[i][j].row*side,grid[i][j].column*side,side,side);
}
}
}
void draw(){}
class Cell
{
boolean isChecked;
int row,column;
int side;
void Cell(int trow, int tcolumn){
row=trow;
column=tcolumn;
}
void toggleCheck(){
if(isChecked == true){
isChecked = false;
}else{
isChecked = true;
}
}
}
The error I got after i tried to ran the program is : The constructor sketch.Cell(int,int) is undefined.
Thank you in advance.
I'm assuming this is Java, although you haven't specified a language. If so, this is the problem:
void Cell(int trow, int tcolumn){
row=trow;
column=tcolumn;
}
That's not a constructor. That's a method called Cell, with a void return type. You meant:
Cell(int trow, int tcolumn){
row=trow;
column=tcolumn;
}
(Or possibly public Cell(...).)
At that point, you should be okay. Note that this would have been a compile-time error - not an execution-time error. Don't try to run your code until it compiles.
Also, it's not clear why you've made your constructor parameters trow and tcolumn - what's the t meant to be for? I'd also make your variables private, and final if possible, and simplify your toggleCheck method. For example:
public final class Cell {
private final int row, column;
private boolean checked;
// It's not clear what side was for
public Cell(int row, int column) {
this.row = row;
this.column = column;
}
public void toggleChecked() {
checked = !checked;
}
public boolean isChecked() {
return checked;
}
}
#DataPoints public static final Integer[] input1={1,2};
#Theory
#Test
public void test1(int input1){
}
#DataPoints public static final Integer[] input2={3,4};
#Theory
#Test
public void test2(int input2 ){
}
I want that test1 runs with data set input1 - {1,2} and test2 runs with input2 - {3,4}. But currently each test runs with both the data sets {1,2,3,4}. How to bind specific #DataPoints to specific #Theorys
With JUnit 4.12 (not sure when it was introduced) it is possible to name the DataPoints and assign them to parameters (i learned it from http://farenda.com/junit/junit-theories-with-datapoints/):
#RunWith(Theories.class)
public class TheoriesAndDataPointsTest {
#DataPoints("a values")
public static int[] aValues() {
return new int[]{1, 2};
}
#DataPoints("b values")
public static int[] bValues() {
return new int[]{3, 4};
}
#Theory
public void theoryForA(#FromDataPoints("a values") int a) {
System.out.printf("TheoryForA called with a = %d\n", a);
}
#Theory
public void theoryForB(#FromDataPoints("b values") int a) {
System.out.printf("TheoryForB called with b = %d\n", a);
}
}
Output:
TheoryForA called with a = 1
TheoryForA called with a = 2
TheoryForB called with b = 3
TheoryForB called with b = 4
DataPoints apply to the class. If you have a #Theory method which takes an int, and you have a DataPoint which is an array of ints, then it will be called with the int.
#RunWith(Theories.class)
public class TheoryTest {
#DataPoint public static int input1 = 45;
#DataPoint public static int input2 = 46;
#DataPoints public static String[] inputs = new String[] { "foobar", "barbar" };
#Theory public void testString1(String input) {
System.out.println("testString1 input=" + input);
}
#Theory public void testString2(String input) {
System.out.println("testString2 input=" + input);
}
#Theory public void test1(int input) {
System.out.println("test1 input=" + input);
}
#Theory public void test2(int input) {
System.out.println("test2 input=" + input);
}
}
This calls test1 with 45 & 46, and test2 with 45 & 46. It calls testString1 with "foobar" and "barbar" and testString2 with "foobar" and "barbar".
If you really want to use different data sets for different theories, you can wrap the data in a private class:
#RunWith(Theories.class)
public class TheoryTest {
public static class I1 { int i; public I1(int i) { this.i = i;} }
public static class I2 { int i; public I2(int i) { this.i = i;} }
#DataPoint public static I1 input1 = new I1(45);
#DataPoint public static I2 input2 = new I2(46);
#Theory
public void test1(I1 input) {
System.out.println("test1 input=" + input.i);
}
#Theory
public void test2(I2 input) {
System.out.println("test2 input=" + input.i);
}
}
This calls test1 with 45 and test2 with 46. This works, but in my opinion, it obscures the code, and it may be a better solution to just split the Test class into two classes.
In reference to Gábor Lipták's answer, named datapoints can be defined as a static fields (reference) which give us more concise code:
#RunWith(Theories.class)
public class TheoriesAndDataPointsTest {
#DataPoints("a values")
public static int[] aValues = {1, 2};
#DataPoints("b values")
public static int[] bValues = {3, 4};
#Theory
public void theoryForA(#FromDataPoints("a values") int a) {
System.out.printf("TheoryForA called with a = %d\n", a);
}
#Theory
public void theoryForB(#FromDataPoints("b values") int a) {
System.out.printf("TheoryForB called with b = %d\n", a);
}
}
Some of the references I have seen talking about using tests for specific values and theories for verifying behavior. As an example, if you have a class that has methods to add and subtract from an attribute, a test would verify correctness of the result (e.g., 1+3 returns 4) whereas a theory might verify that, for the datapoint values (x1, y1), (x2, y2), x+y-y always equals x, x-y+y always equals x, x*y/y always equals x, etc. This way, the results of theories are not coupled as tightly with the data. With theories, you also can filter out cases such as y == 0; they don't count as failure. Bottom line: you can use both. A good paper is: http://web.archive.org/web/20110608210825/http://shareandenjoy.saff.net/tdd-specifications.pdf
I know how to do it using simple recursion, but in order to complete this particular assignment I need to be able to accumulate on the stack and throw an exception that holds the answer in it.
So far I have:
public static int fibo(int index) {
int sum = 0;
try {
fibo_aux(index, 1, 1);
}
catch (IntegerException me) {
sum = me.getIntValue();
}
return sum;
}
fibo_aux is supposed to throw an IntegerException (which holds the value of the answer that is retireved via getIntValue) and accumulates the answer on the stack, but so far I can't figure it out. Can anyone help?
I don't know what your implementations for fibo_aux and IntegerException look like, but the following two implementations work with your existing code (I don't think there's anything wrong with the code you posted, so I assume something is awry in either fibo_aux or IntegerException). Maybe you'll find this helpful.
public static void fibo_aux(int index, int a, int b) throws IntegerException
{
if (--index > 0)
fibo_aux(index, b, a + b);
else
throw new IntegerException(a + b);
}
An implementation for IntegerException:
public class IntegerException extends Exception
{
private static final long serialVersionUID = -6795044518321782305L;
private Integer intValue;
public IntegerException(int i)
{
this.intValue = i;
}
public Integer getIntValue()
{
return intValue;
}
}
Here you go :
public class ExcFib {
/**
* #param args
*/
public static void main(String[] args) {
new ExcFib().fibo ( 10 );
}
class FiboException extends Throwable
{
public int n;
public FiboException(int n)
{
this.n = n;
}
private static final long serialVersionUID = 1L;
}
public void fibo(int idx) {
try {
fibo_aux(idx-1,1,1);
} catch (FiboException e) {
System.out.println ( "F(" + idx + ") = " + e.n );
}
}
private void fibo_aux(int i, int j, int k) throws FiboException {
if ( i < 1 )
{
throw new FiboException(k);
}
fibo_aux(i - 1, k, j + k );
}
}